/**
 * interact.js v1.3.4
 *
 * Copyright (c) 2012-2018 Taye Adeyemi <dev@taye.me>
 * Released under the MIT License.
 * https://raw.github.com/taye/interact.js/master/LICENSE
 */
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.interact = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
    'use strict';
    
    /*
     * In a (windowless) server environment this file exports a factory function
     * that takes the window to use.
     *
     *     var interact = require('interact.js')(windowObject);
     *
     * See https://github.com/taye/interact.js/issues/187
     */
    if (typeof window === 'undefined') {
      module.exports = function (window) {
        require('./src/utils/window').init(window);
    
        return require('./src/index');
      };
    } else {
      module.exports = require('./src/index');
    }
    
    },{"./src/index":19,"./src/utils/window":52}],2:[function(require,module,exports){
    'use strict';
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var extend = require('./utils/extend.js');
    
    function fireUntilImmediateStopped(event, listeners) {
      for (var _i = 0; _i < listeners.length; _i++) {
        var _ref;
    
        _ref = listeners[_i];
        var listener = _ref;
    
        if (event.immediatePropagationStopped) {
          break;
        }
    
        listener(event);
      }
    }
    
    var Eventable = function () {
      function Eventable(options) {
        _classCallCheck(this, Eventable);
    
        this.options = extend({}, options || {});
      }
    
      Eventable.prototype.fire = function fire(event) {
        var listeners = void 0;
        var onEvent = 'on' + event.type;
        var global = this.global;
    
        // Interactable#on() listeners
        if (listeners = this[event.type]) {
          fireUntilImmediateStopped(event, listeners);
        }
    
        // interactable.onevent listener
        if (this[onEvent]) {
          this[onEvent](event);
        }
    
        // interact.on() listeners
        if (!event.propagationStopped && global && (listeners = global[event.type])) {
          fireUntilImmediateStopped(event, listeners);
        }
      };
    
      Eventable.prototype.on = function on(eventType, listener) {
        // if this type of event was never bound
        if (this[eventType]) {
          this[eventType].push(listener);
        } else {
          this[eventType] = [listener];
        }
      };
    
      Eventable.prototype.off = function off(eventType, listener) {
        // if it is an action event type
        var eventList = this[eventType];
        var index = eventList ? eventList.indexOf(listener) : -1;
    
        if (index !== -1) {
          eventList.splice(index, 1);
        }
    
        if (eventList && eventList.length === 0 || !listener) {
          this[eventType] = undefined;
        }
      };
    
      return Eventable;
    }();
    
    module.exports = Eventable;
    
    },{"./utils/extend.js":41}],3:[function(require,module,exports){
    'use strict';
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var extend = require('./utils/extend');
    var getOriginXY = require('./utils/getOriginXY');
    var defaults = require('./defaultOptions');
    var signals = require('./utils/Signals').new();
    
    var InteractEvent = function () {
      /** */
      function InteractEvent(interaction, event, action, phase, element, related) {
        var preEnd = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
    
        _classCallCheck(this, InteractEvent);
    
        var target = interaction.target;
        var deltaSource = (target && target.options || defaults).deltaSource;
        var origin = getOriginXY(target, element, action);
        var starting = phase === 'start';
        var ending = phase === 'end';
        var coords = starting ? interaction.startCoords : interaction.curCoords;
        var prevEvent = interaction.prevEvent;
    
        element = element || interaction.element;
    
        var page = extend({}, coords.page);
        var client = extend({}, coords.client);
    
        page.x -= origin.x;
        page.y -= origin.y;
    
        client.x -= origin.x;
        client.y -= origin.y;
    
        this.ctrlKey = event.ctrlKey;
        this.altKey = event.altKey;
        this.shiftKey = event.shiftKey;
        this.metaKey = event.metaKey;
        this.button = event.button;
        this.buttons = event.buttons;
        this.target = element;
        this.currentTarget = element;
        this.relatedTarget = related || null;
        this.preEnd = preEnd;
        this.type = action + (phase || '');
        this.interaction = interaction;
        this.interactable = target;
    
        this.t0 = starting ? interaction.downTimes[interaction.downTimes.length - 1] : prevEvent.t0;
    
        var signalArg = {
          interaction: interaction,
          event: event,
          action: action,
          phase: phase,
          element: element,
          related: related,
          page: page,
          client: client,
          coords: coords,
          starting: starting,
          ending: ending,
          deltaSource: deltaSource,
          iEvent: this
        };
    
        signals.fire('set-xy', signalArg);
    
        if (ending) {
          // use previous coords when ending
          this.pageX = prevEvent.pageX;
          this.pageY = prevEvent.pageY;
          this.clientX = prevEvent.clientX;
          this.clientY = prevEvent.clientY;
        } else {
          this.pageX = page.x;
          this.pageY = page.y;
          this.clientX = client.x;
          this.clientY = client.y;
        }
    
        this.x0 = interaction.startCoords.page.x - origin.x;
        this.y0 = interaction.startCoords.page.y - origin.y;
        this.clientX0 = interaction.startCoords.client.x - origin.x;
        this.clientY0 = interaction.startCoords.client.y - origin.y;
    
        signals.fire('set-delta', signalArg);
    
        this.timeStamp = coords.timeStamp;
        this.dt = interaction.pointerDelta.timeStamp;
        this.duration = this.timeStamp - this.t0;
    
        // speed and velocity in pixels per second
        this.speed = interaction.pointerDelta[deltaSource].speed;
        this.velocityX = interaction.pointerDelta[deltaSource].vx;
        this.velocityY = interaction.pointerDelta[deltaSource].vy;
    
        this.swipe = ending || phase === 'inertiastart' ? this.getSwipe() : null;
    
        signals.fire('new', signalArg);
      }
    
      InteractEvent.prototype.getSwipe = function getSwipe() {
        var interaction = this.interaction;
    
        if (interaction.prevEvent.speed < 600 || this.timeStamp - interaction.prevEvent.timeStamp > 150) {
          return null;
        }
    
        var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI;
        var overlap = 22.5;
    
        if (angle < 0) {
          angle += 360;
        }
    
        var left = 135 - overlap <= angle && angle < 225 + overlap;
        var up = 225 - overlap <= angle && angle < 315 + overlap;
    
        var right = !left && (315 - overlap <= angle || angle < 45 + overlap);
        var down = !up && 45 - overlap <= angle && angle < 135 + overlap;
    
        return {
          up: up,
          down: down,
          left: left,
          right: right,
          angle: angle,
          speed: interaction.prevEvent.speed,
          velocity: {
            x: interaction.prevEvent.velocityX,
            y: interaction.prevEvent.velocityY
          }
        };
      };
    
      InteractEvent.prototype.preventDefault = function preventDefault() {};
    
      /** */
    
    
      InteractEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {
        this.immediatePropagationStopped = this.propagationStopped = true;
      };
    
      /** */
    
    
      InteractEvent.prototype.stopPropagation = function stopPropagation() {
        this.propagationStopped = true;
      };
    
      return InteractEvent;
    }();
    
    signals.on('set-delta', function (_ref) {
      var iEvent = _ref.iEvent,
          interaction = _ref.interaction,
          starting = _ref.starting,
          deltaSource = _ref.deltaSource;
    
      var prevEvent = starting ? iEvent : interaction.prevEvent;
    
      if (deltaSource === 'client') {
        iEvent.dx = iEvent.clientX - prevEvent.clientX;
        iEvent.dy = iEvent.clientY - prevEvent.clientY;
      } else {
        iEvent.dx = iEvent.pageX - prevEvent.pageX;
        iEvent.dy = iEvent.pageY - prevEvent.pageY;
      }
    });
    
    InteractEvent.signals = signals;
    
    module.exports = InteractEvent;
    
    },{"./defaultOptions":18,"./utils/Signals":34,"./utils/extend":41,"./utils/getOriginXY":42}],4:[function(require,module,exports){
    'use strict';
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var clone = require('./utils/clone');
    var is = require('./utils/is');
    var events = require('./utils/events');
    var extend = require('./utils/extend');
    var actions = require('./actions/base');
    var scope = require('./scope');
    var Eventable = require('./Eventable');
    var defaults = require('./defaultOptions');
    var signals = require('./utils/Signals').new();
    
    var _require = require('./utils/domUtils'),
        getElementRect = _require.getElementRect,
        nodeContains = _require.nodeContains,
        trySelector = _require.trySelector,
        matchesSelector = _require.matchesSelector;
    
    var _require2 = require('./utils/window'),
        getWindow = _require2.getWindow;
    
    var _require3 = require('./utils/arr'),
        contains = _require3.contains;
    
    var _require4 = require('./utils/browser'),
        wheelEvent = _require4.wheelEvent;
    
    // all set interactables
    
    
    scope.interactables = [];
    
    var Interactable = function () {
      /** */
      function Interactable(target, options) {
        _classCallCheck(this, Interactable);
    
        options = options || {};
    
        this.target = target;
        this.events = new Eventable();
        this._context = options.context || scope.document;
        this._win = getWindow(trySelector(target) ? this._context : target);
        this._doc = this._win.document;
    
        signals.fire('new', {
          target: target,
          options: options,
          interactable: this,
          win: this._win
        });
    
        scope.addDocument(this._doc, this._win);
    
        scope.interactables.push(this);
    
        this.set(options);
      }
    
      Interactable.prototype.setOnEvents = function setOnEvents(action, phases) {
        var onAction = 'on' + action;
    
        if (is.function(phases.onstart)) {
          this.events[onAction + 'start'] = phases.onstart;
        }
        if (is.function(phases.onmove)) {
          this.events[onAction + 'move'] = phases.onmove;
        }
        if (is.function(phases.onend)) {
          this.events[onAction + 'end'] = phases.onend;
        }
        if (is.function(phases.oninertiastart)) {
          this.events[onAction + 'inertiastart'] = phases.oninertiastart;
        }
    
        return this;
      };
    
      Interactable.prototype.setPerAction = function setPerAction(action, options) {
        // for all the default per-action options
        for (var option in options) {
          // if this option exists for this action
          if (option in defaults[action]) {
            // if the option in the options arg is an object value
            if (is.object(options[option])) {
              // duplicate the object and merge
              this.options[action][option] = clone(this.options[action][option] || {});
              extend(this.options[action][option], options[option]);
    
              if (is.object(defaults.perAction[option]) && 'enabled' in defaults.perAction[option]) {
                this.options[action][option].enabled = options[option].enabled === false ? false : true;
              }
            } else if (is.bool(options[option]) && is.object(defaults.perAction[option])) {
              this.options[action][option].enabled = options[option];
            } else if (options[option] !== undefined) {
              // or if it's not undefined, do a plain assignment
              this.options[action][option] = options[option];
            }
          }
        }
      };
    
      /**
       * The default function to get an Interactables bounding rect. Can be
       * overridden using {@link Interactable.rectChecker}.
       *
       * @param {Element} [element] The element to measure.
       * @return {object} The object's bounding rectangle.
       */
    
    
      Interactable.prototype.getRect = function getRect(element) {
        element = element || this.target;
    
        if (is.string(this.target) && !is.element(element)) {
          element = this._context.querySelector(this.target);
        }
    
        return getElementRect(element);
      };
    
      /**
       * Returns or sets the function used to calculate the interactable's
       * element's rectangle
       *
       * @param {function} [checker] A function which returns this Interactable's
       * bounding rectangle. See {@link Interactable.getRect}
       * @return {function | object} The checker function or this Interactable
       */
    
    
      Interactable.prototype.rectChecker = function rectChecker(checker) {
        if (is.function(checker)) {
          this.getRect = checker;
    
          return this;
        }
    
        if (checker === null) {
          delete this.options.getRect;
    
          return this;
        }
    
        return this.getRect;
      };
    
      Interactable.prototype._backCompatOption = function _backCompatOption(optionName, newValue) {
        if (trySelector(newValue) || is.object(newValue)) {
          this.options[optionName] = newValue;
    
          for (var _i = 0; _i < actions.names.length; _i++) {
            var _ref;
    
            _ref = actions.names[_i];
            var action = _ref;
    
            this.options[action][optionName] = newValue;
          }
    
          return this;
        }
    
        return this.options[optionName];
      };
    
      /**
       * Gets or sets the origin of the Interactable's element.  The x and y
       * of the origin will be subtracted from action event coordinates.
       *
       * @param {Element | object | string} [origin] An HTML or SVG Element whose
       * rect will be used, an object eg. { x: 0, y: 0 } or string 'parent', 'self'
       * or any CSS selector
       *
       * @return {object} The current origin or this Interactable
       */
    
    
      Interactable.prototype.origin = function origin(newValue) {
        return this._backCompatOption('origin', newValue);
      };
    
      /**
       * Returns or sets the mouse coordinate types used to calculate the
       * movement of the pointer.
       *
       * @param {string} [newValue] Use 'client' if you will be scrolling while
       * interacting; Use 'page' if you want autoScroll to work
       * @return {string | object} The current deltaSource or this Interactable
       */
    
    
      Interactable.prototype.deltaSource = function deltaSource(newValue) {
        if (newValue === 'page' || newValue === 'client') {
          this.options.deltaSource = newValue;
    
          return this;
        }
    
        return this.options.deltaSource;
      };
    
      /**
       * Gets the selector context Node of the Interactable. The default is
       * `window.document`.
       *
       * @return {Node} The context Node of this Interactable
       */
    
    
      Interactable.prototype.context = function context() {
        return this._context;
      };
    
      Interactable.prototype.inContext = function inContext(element) {
        return this._context === element.ownerDocument || nodeContains(this._context, element);
      };
    
      /**
       * Calls listeners for the given InteractEvent type bound globally
       * and directly to this Interactable
       *
       * @param {InteractEvent} iEvent The InteractEvent object to be fired on this
       * Interactable
       * @return {Interactable} this Interactable
       */
    
    
      Interactable.prototype.fire = function fire(iEvent) {
        this.events.fire(iEvent);
    
        return this;
      };
    
      Interactable.prototype._onOffMultiple = function _onOffMultiple(method, eventType, listener, options) {
        if (is.string(eventType) && eventType.search(' ') !== -1) {
          eventType = eventType.trim().split(/ +/);
        }
    
        if (is.array(eventType)) {
          for (var _i2 = 0; _i2 < eventType.length; _i2++) {
            var _ref2;
    
            _ref2 = eventType[_i2];
            var type = _ref2;
    
            this[method](type, listener, options);
          }
    
          return true;
        }
    
        if (is.object(eventType)) {
          for (var prop in eventType) {
            this[method](prop, eventType[prop], listener);
          }
    
          return true;
        }
      };
    
      /**
       * Binds a listener for an InteractEvent, pointerEvent or DOM event.
       *
       * @param {string | array | object} eventType  The types of events to listen
       * for
       * @param {function} listener   The function event (s)
       * @param {object | boolean} [options]    options object or useCapture flag
       * for addEventListener
       * @return {object} This Interactable
       */
    
    
      Interactable.prototype.on = function on(eventType, listener, options) {
        if (this._onOffMultiple('on', eventType, listener, options)) {
          return this;
        }
    
        if (eventType === 'wheel') {
          eventType = wheelEvent;
        }
    
        if (contains(Interactable.eventTypes, eventType)) {
          this.events.on(eventType, listener);
        }
        // delegated event for selector
        else if (is.string(this.target)) {
            events.addDelegate(this.target, this._context, eventType, listener, options);
          } else {
            events.add(this.target, eventType, listener, options);
          }
    
        return this;
      };
    
      /**
       * Removes an InteractEvent, pointerEvent or DOM event listener
       *
       * @param {string | array | object} eventType The types of events that were
       * listened for
       * @param {function} listener The listener function to be removed
       * @param {object | boolean} [options] options object or useCapture flag for
       * removeEventListener
       * @return {object} This Interactable
       */
    
    
      Interactable.prototype.off = function off(eventType, listener, options) {
        if (this._onOffMultiple('off', eventType, listener, options)) {
          return this;
        }
    
        if (eventType === 'wheel') {
          eventType = wheelEvent;
        }
    
        // if it is an action event type
        if (contains(Interactable.eventTypes, eventType)) {
          this.events.off(eventType, listener);
        }
        // delegated event
        else if (is.string(this.target)) {
            events.removeDelegate(this.target, this._context, eventType, listener, options);
          }
          // remove listener from this Interatable's element
          else {
              events.remove(this.target, eventType, listener, options);
            }
    
        return this;
      };
    
      /**
       * Reset the options of this Interactable
       *
       * @param {object} options The new settings to apply
       * @return {object} This Interactable
       */
    
    
      Interactable.prototype.set = function set(options) {
        if (!is.object(options)) {
          options = {};
        }
    
        this.options = clone(defaults.base);
    
        var perActions = clone(defaults.perAction);
    
        for (var actionName in actions.methodDict) {
          var methodName = actions.methodDict[actionName];
    
          this.options[actionName] = clone(defaults[actionName]);
    
          this.setPerAction(actionName, perActions);
    
          this[methodName](options[actionName]);
        }
    
        for (var _i3 = 0; _i3 < Interactable.settingsMethods.length; _i3++) {
          var _ref3;
    
          _ref3 = Interactable.settingsMethods[_i3];
          var setting = _ref3;
    
          this.options[setting] = defaults.base[setting];
    
          if (setting in options) {
            this[setting](options[setting]);
          }
        }
    
        signals.fire('set', {
          options: options,
          interactable: this
        });
    
        return this;
      };
    
      /**
       * Remove this interactable from the list of interactables and remove it's
       * action capabilities and event listeners
       *
       * @return {interact}
       */
    
    
      Interactable.prototype.unset = function unset() {
        events.remove(this.target, 'all');
    
        if (is.string(this.target)) {
          // remove delegated events
          for (var type in events.delegatedEvents) {
            var delegated = events.delegatedEvents[type];
    
            if (delegated.selectors[0] === this.target && delegated.contexts[0] === this._context) {
    
              delegated.selectors.splice(0, 1);
              delegated.contexts.splice(0, 1);
              delegated.listeners.splice(0, 1);
    
              // remove the arrays if they are empty
              if (!delegated.selectors.length) {
                delegated[type] = null;
              }
            }
    
            events.remove(this._context, type, events.delegateListener);
            events.remove(this._context, type, events.delegateUseCapture, true);
          }
        } else {
          events.remove(this, 'all');
        }
    
        signals.fire('unset', { interactable: this });
    
        scope.interactables.splice(scope.interactables.indexOf(this), 1);
    
        // Stop related interactions when an Interactable is unset
        for (var _i4 = 0; _i4 < (scope.interactions || []).length; _i4++) {
          var _ref4;
    
          _ref4 = (scope.interactions || [])[_i4];
          var interaction = _ref4;
    
          if (interaction.target === this && interaction.interacting() && !interaction._ending) {
            interaction.stop();
          }
        }
    
        return scope.interact;
      };
    
      return Interactable;
    }();
    
    scope.interactables.indexOfElement = function indexOfElement(target, context) {
      context = context || scope.document;
    
      for (var i = 0; i < this.length; i++) {
        var interactable = this[i];
    
        if (interactable.target === target && interactable._context === context) {
          return i;
        }
      }
      return -1;
    };
    
    scope.interactables.get = function interactableGet(element, options, dontCheckInContext) {
      var ret = this[this.indexOfElement(element, options && options.context)];
    
      return ret && (is.string(element) || dontCheckInContext || ret.inContext(element)) ? ret : null;
    };
    
    scope.interactables.forEachMatch = function (element, callback) {
      for (var _i5 = 0; _i5 < this.length; _i5++) {
        var _ref5;
    
        _ref5 = this[_i5];
        var interactable = _ref5;
    
        var ret = void 0;
    
        if ((is.string(interactable.target)
        // target is a selector and the element matches
        ? is.element(element) && matchesSelector(element, interactable.target) :
        // target is the element
        element === interactable.target) &&
        // the element is in context
        interactable.inContext(element)) {
          ret = callback(interactable);
        }
    
        if (ret !== undefined) {
          return ret;
        }
      }
    };
    
    // all interact.js eventTypes
    Interactable.eventTypes = scope.eventTypes = [];
    
    Interactable.signals = signals;
    
    Interactable.settingsMethods = ['deltaSource', 'origin', 'preventDefault', 'rectChecker'];
    
    module.exports = Interactable;
    
    },{"./Eventable":2,"./actions/base":6,"./defaultOptions":18,"./scope":33,"./utils/Signals":34,"./utils/arr":35,"./utils/browser":36,"./utils/clone":37,"./utils/domUtils":39,"./utils/events":40,"./utils/extend":41,"./utils/is":46,"./utils/window":52}],5:[function(require,module,exports){
    'use strict';
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var scope = require('./scope');
    var utils = require('./utils');
    var events = require('./utils/events');
    var browser = require('./utils/browser');
    var domObjects = require('./utils/domObjects');
    var finder = require('./utils/interactionFinder');
    var signals = require('./utils/Signals').new();
    
    var listeners = {};
    var methodNames = ['pointerDown', 'pointerMove', 'pointerUp', 'updatePointer', 'removePointer'];
    
    // for ignoring browser's simulated mouse events
    var prevTouchTime = 0;
    
    // all active and idle interactions
    scope.interactions = [];
    
    var Interaction = function () {
      /** */
      function Interaction(_ref) {
        var pointerType = _ref.pointerType;
    
        _classCallCheck(this, Interaction);
    
        this.target = null; // current interactable being interacted with
        this.element = null; // the target element of the interactable
    
        this.prepared = { // action that's ready to be fired on next move event
          name: null,
          axis: null,
          edges: null
        };
    
        // keep track of added pointers
        this.pointers = [];
        this.pointerIds = [];
        this.downTargets = [];
        this.downTimes = [];
    
        // Previous native pointer move event coordinates
        this.prevCoords = {
          page: { x: 0, y: 0 },
          client: { x: 0, y: 0 },
          timeStamp: 0
        };
        // current native pointer move event coordinates
        this.curCoords = {
          page: { x: 0, y: 0 },
          client: { x: 0, y: 0 },
          timeStamp: 0
        };
    
        // Starting InteractEvent pointer coordinates
        this.startCoords = {
          page: { x: 0, y: 0 },
          client: { x: 0, y: 0 },
          timeStamp: 0
        };
    
        // Change in coordinates and time of the pointer
        this.pointerDelta = {
          page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },
          client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },
          timeStamp: 0
        };
    
        this.downEvent = null; // pointerdown/mousedown/touchstart event
        this.downPointer = {};
    
        this._eventTarget = null;
        this._curEventTarget = null;
    
        this.prevEvent = null; // previous action event
    
        this.pointerIsDown = false;
        this.pointerWasMoved = false;
        this._interacting = false;
        this._ending = false;
    
        this.pointerType = pointerType;
    
        signals.fire('new', this);
    
        scope.interactions.push(this);
      }
    
      Interaction.prototype.pointerDown = function pointerDown(pointer, event, eventTarget) {
        var pointerIndex = this.updatePointer(pointer, event, true);
    
        signals.fire('down', {
          pointer: pointer,
          event: event,
          eventTarget: eventTarget,
          pointerIndex: pointerIndex,
          interaction: this
        });
      };
    
      /**
       * ```js
       * interact(target)
       *   .draggable({
       *     // disable the default drag start by down->move
       *     manualStart: true
       *   })
       *   // start dragging after the user holds the pointer down
       *   .on('hold', function (event) {
       *     var interaction = event.interaction;
       *
       *     if (!interaction.interacting()) {
       *       interaction.start({ name: 'drag' },
       *                         event.interactable,
       *                         event.currentTarget);
       *     }
       * });
       * ```
       *
       * Start an action with the given Interactable and Element as tartgets. The
       * action must be enabled for the target Interactable and an appropriate
       * number of pointers must be held down - 1 for drag/resize, 2 for gesture.
       *
       * Use it with `interactable.<action>able({ manualStart: false })` to always
       * [start actions manually](https://github.com/taye/interact.js/issues/114)
       *
       * @param {object} action   The action to be performed - drag, resize, etc.
       * @param {Interactable} target  The Interactable to target
       * @param {Element} element The DOM Element to target
       * @return {object} interact
       */
    
    
      Interaction.prototype.start = function start(action, target, element) {
        if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {
          return;
        }
    
        // if this interaction had been removed after stopping
        // add it back
        if (scope.interactions.indexOf(this) === -1) {
          scope.interactions.push(this);
        }
    
        utils.copyAction(this.prepared, action);
        this.target = target;
        this.element = element;
    
        signals.fire('action-start', {
          interaction: this,
          event: this.downEvent
        });
      };
    
      Interaction.prototype.pointerMove = function pointerMove(pointer, event, eventTarget) {
        if (!this.simulation) {
          this.updatePointer(pointer);
          utils.setCoords(this.curCoords, this.pointers);
        }
    
        var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;
    
        var dx = void 0;
        var dy = void 0;
    
        // register movement greater than pointerMoveTolerance
        if (this.pointerIsDown && !this.pointerWasMoved) {
          dx = this.curCoords.client.x - this.startCoords.client.x;
          dy = this.curCoords.client.y - this.startCoords.client.y;
    
          this.pointerWasMoved = utils.hypot(dx, dy) > Interaction.pointerMoveTolerance;
        }
    
        var signalArg = {
          pointer: pointer,
          pointerIndex: this.getPointerIndex(pointer),
          event: event,
          eventTarget: eventTarget,
          dx: dx,
          dy: dy,
          duplicate: duplicateMove,
          interaction: this,
          interactingBeforeMove: this.interacting()
        };
    
        if (!duplicateMove) {
          // set pointer coordinate, time changes and speeds
          utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);
        }
    
        signals.fire('move', signalArg);
    
        if (!duplicateMove) {
          // if interacting, fire an 'action-move' signal etc
          if (this.interacting()) {
            this.doMove(signalArg);
          }
    
          if (this.pointerWasMoved) {
            utils.copyCoords(this.prevCoords, this.curCoords);
          }
        }
      };
    
      /**
       * ```js
       * interact(target)
       *   .draggable(true)
       *   .on('dragmove', function (event) {
       *     if (someCondition) {
       *       // change the snap settings
       *       event.interactable.draggable({ snap: { targets: [] }});
       *       // fire another move event with re-calculated snap
       *       event.interaction.doMove();
       *     }
       *   });
       * ```
       *
       * Force a move of the current action at the same coordinates. Useful if
       * snap/restrict has been changed and you want a movement with the new
       * settings.
       */
    
    
      Interaction.prototype.doMove = function doMove(signalArg) {
        signalArg = utils.extend({
          pointer: this.pointers[0],
          event: this.prevEvent,
          eventTarget: this._eventTarget,
          interaction: this
        }, signalArg || {});
    
        signals.fire('before-action-move', signalArg);
    
        if (!this._dontFireMove) {
          signals.fire('action-move', signalArg);
        }
    
        this._dontFireMove = false;
      };
    
      // End interact move events and stop auto-scroll unless simulation is running
    
    
      Interaction.prototype.pointerUp = function pointerUp(pointer, event, eventTarget, curEventTarget) {
        var pointerIndex = this.getPointerIndex(pointer);
    
        signals.fire(/cancel$/i.test(event.type) ? 'cancel' : 'up', {
          pointer: pointer,
          pointerIndex: pointerIndex,
          event: event,
          eventTarget: eventTarget,
          curEventTarget: curEventTarget,
          interaction: this
        });
    
        if (!this.simulation) {
          this.end(event);
        }
    
        this.pointerIsDown = false;
        this.removePointer(pointer, event);
      };
    
      /**
       * ```js
       * interact(target)
       *   .draggable(true)
       *   .on('move', function (event) {
       *     if (event.pageX > 1000) {
       *       // end the current action
       *       event.interaction.end();
       *       // stop all further listeners from being called
       *       event.stopImmediatePropagation();
       *     }
       *   });
       * ```
       *
       * Stop the current action and fire an end event. Inertial movement does
       * not happen.
       *
       * @param {PointerEvent} [event]
       */
    
    
      Interaction.prototype.end = function end(event) {
        this._ending = true;
    
        event = event || this.prevEvent;
    
        if (this.interacting()) {
          signals.fire('action-end', {
            event: event,
            interaction: this
          });
        }
    
        this.stop();
        this._ending = false;
      };
    
      Interaction.prototype.currentAction = function currentAction() {
        return this._interacting ? this.prepared.name : null;
      };
    
      Interaction.prototype.interacting = function interacting() {
        return this._interacting;
      };
    
      /** */
    
    
      Interaction.prototype.stop = function stop() {
        signals.fire('stop', { interaction: this });
    
        if (this._interacting) {
          signals.fire('stop-active', { interaction: this });
          signals.fire('stop-' + this.prepared.name, { interaction: this });
        }
    
        this.target = this.element = null;
    
        this._interacting = false;
        this.prepared.name = this.prevEvent = null;
      };
    
      Interaction.prototype.getPointerIndex = function getPointerIndex(pointer) {
        // mouse and pen interactions may have only one pointer
        if (this.pointerType === 'mouse' || this.pointerType === 'pen') {
          return 0;
        }
    
        return this.pointerIds.indexOf(utils.getPointerId(pointer));
      };
    
      Interaction.prototype.updatePointer = function updatePointer(pointer, event) {
        var down = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : event && /(down|start)$/i.test(event.type);
    
        var id = utils.getPointerId(pointer);
        var index = this.getPointerIndex(pointer);
    
        if (index === -1) {
          index = this.pointerIds.length;
          this.pointerIds[index] = id;
        }
    
        if (down) {
          signals.fire('update-pointer-down', {
            pointer: pointer,
            event: event,
            down: down,
            pointerId: id,
            pointerIndex: index,
            interaction: this
          });
        }
    
        this.pointers[index] = pointer;
    
        return index;
      };
    
      Interaction.prototype.removePointer = function removePointer(pointer, event) {
        var index = this.getPointerIndex(pointer);
    
        if (index === -1) {
          return;
        }
    
        signals.fire('remove-pointer', {
          pointer: pointer,
          event: event,
          pointerIndex: index,
          interaction: this
        });
    
        this.pointers.splice(index, 1);
        this.pointerIds.splice(index, 1);
        this.downTargets.splice(index, 1);
        this.downTimes.splice(index, 1);
      };
    
      Interaction.prototype._updateEventTargets = function _updateEventTargets(target, currentTarget) {
        this._eventTarget = target;
        this._curEventTarget = currentTarget;
      };
    
      return Interaction;
    }();
    
    for (var _i = 0; _i < methodNames.length; _i++) {
      var method = methodNames[_i];
      listeners[method] = doOnInteractions(method);
    }
    
    function doOnInteractions(method) {
      return function (event) {
        var pointerType = utils.getPointerType(event);
    
        var _utils$getEventTarget = utils.getEventTargets(event),
            eventTarget = _utils$getEventTarget[0],
            curEventTarget = _utils$getEventTarget[1];
    
        var matches = []; // [ [pointer, interaction], ...]
    
        if (browser.supportsTouch && /touch/.test(event.type)) {
          prevTouchTime = new Date().getTime();
    
          for (var _i2 = 0; _i2 < event.changedTouches.length; _i2++) {
            var _ref2;
    
            _ref2 = event.changedTouches[_i2];
            var changedTouch = _ref2;
    
            var pointer = changedTouch;
            var interaction = finder.search(pointer, event.type, eventTarget);
    
            matches.push([pointer, interaction || new Interaction({ pointerType: pointerType })]);
          }
        } else {
          var invalidPointer = false;
    
          if (!browser.supportsPointerEvent && /mouse/.test(event.type)) {
            // ignore mouse events while touch interactions are active
            for (var i = 0; i < scope.interactions.length && !invalidPointer; i++) {
              invalidPointer = scope.interactions[i].pointerType !== 'mouse' && scope.interactions[i].pointerIsDown;
            }
    
            // try to ignore mouse events that are simulated by the browser
            // after a touch event
            invalidPointer = invalidPointer || new Date().getTime() - prevTouchTime < 500
            // on iOS and Firefox Mobile, MouseEvent.timeStamp is zero if simulated
            || event.timeStamp === 0;
          }
    
          if (!invalidPointer) {
            var _interaction = finder.search(event, event.type, eventTarget);
    
            if (!_interaction) {
              _interaction = new Interaction({ pointerType: pointerType });
            }
    
            matches.push([event, _interaction]);
          }
        }
    
        for (var _i3 = 0; _i3 < matches.length; _i3++) {
          var _ref3 = matches[_i3];
          var _pointer = _ref3[0];
          var _interaction2 = _ref3[1];
    
          _interaction2._updateEventTargets(eventTarget, curEventTarget);
          _interaction2[method](_pointer, event, eventTarget, curEventTarget);
        }
      };
    }
    
    function endAll(event) {
      for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {
        var _ref4;
    
        _ref4 = scope.interactions[_i4];
        var interaction = _ref4;
    
        interaction.end(event);
        signals.fire('endall', { event: event, interaction: interaction });
      }
    }
    
    var docEvents = {/* 'eventType': listenerFunc */};
    var pEventTypes = browser.pEventTypes;
    
    if (domObjects.PointerEvent) {
      docEvents[pEventTypes.down] = listeners.pointerDown;
      docEvents[pEventTypes.move] = listeners.pointerMove;
      docEvents[pEventTypes.up] = listeners.pointerUp;
      docEvents[pEventTypes.cancel] = listeners.pointerUp;
    } else {
      docEvents.mousedown = listeners.pointerDown;
      docEvents.mousemove = listeners.pointerMove;
      docEvents.mouseup = listeners.pointerUp;
    
      docEvents.touchstart = listeners.pointerDown;
      docEvents.touchmove = listeners.pointerMove;
      docEvents.touchend = listeners.pointerUp;
      docEvents.touchcancel = listeners.pointerUp;
    }
    
    docEvents.blur = endAll;
    
    function onDocSignal(_ref5, signalName) {
      var doc = _ref5.doc;
    
      var eventMethod = signalName.indexOf('add') === 0 ? events.add : events.remove;
    
      // delegate event listener
      for (var eventType in scope.delegatedEvents) {
        eventMethod(doc, eventType, events.delegateListener);
        eventMethod(doc, eventType, events.delegateUseCapture, true);
      }
    
      for (var _eventType in docEvents) {
        eventMethod(doc, _eventType, docEvents[_eventType], browser.isIOS ? { passive: false } : undefined);
      }
    }
    
    signals.on('update-pointer-down', function (_ref6) {
      var interaction = _ref6.interaction,
          pointer = _ref6.pointer,
          pointerId = _ref6.pointerId,
          pointerIndex = _ref6.pointerIndex,
          event = _ref6.event,
          eventTarget = _ref6.eventTarget,
          down = _ref6.down;
    
      interaction.pointerIds[pointerIndex] = pointerId;
      interaction.pointers[pointerIndex] = pointer;
    
      if (down) {
        interaction.pointerIsDown = true;
      }
    
      if (!interaction.interacting()) {
        utils.setCoords(interaction.startCoords, interaction.pointers);
    
        utils.copyCoords(interaction.curCoords, interaction.startCoords);
        utils.copyCoords(interaction.prevCoords, interaction.startCoords);
    
        interaction.downEvent = event;
        interaction.downTimes[pointerIndex] = interaction.curCoords.timeStamp;
        interaction.downTargets[pointerIndex] = eventTarget || event && utils.getEventTargets(event)[0];
        interaction.pointerWasMoved = false;
    
        utils.pointerExtend(interaction.downPointer, pointer);
      }
    });
    
    scope.signals.on('add-document', onDocSignal);
    scope.signals.on('remove-document', onDocSignal);
    
    Interaction.pointerMoveTolerance = 1;
    Interaction.doOnInteractions = doOnInteractions;
    Interaction.endAll = endAll;
    Interaction.signals = signals;
    Interaction.docEvents = docEvents;
    
    scope.endAllInteractions = endAll;
    
    module.exports = Interaction;
    
    },{"./scope":33,"./utils":44,"./utils/Signals":34,"./utils/browser":36,"./utils/domObjects":38,"./utils/events":40,"./utils/interactionFinder":45}],6:[function(require,module,exports){
    'use strict';
    
    var Interaction = require('../Interaction');
    var InteractEvent = require('../InteractEvent');
    
    var actions = {
      firePrepared: firePrepared,
      names: [],
      methodDict: {}
    };
    
    Interaction.signals.on('action-start', function (_ref) {
      var interaction = _ref.interaction,
          event = _ref.event;
    
      interaction._interacting = true;
      firePrepared(interaction, event, 'start');
    });
    
    Interaction.signals.on('action-move', function (_ref2) {
      var interaction = _ref2.interaction,
          event = _ref2.event,
          preEnd = _ref2.preEnd;
    
      firePrepared(interaction, event, 'move', preEnd);
    
      // if the action was ended in a listener
      if (!interaction.interacting()) {
        return false;
      }
    });
    
    Interaction.signals.on('action-end', function (_ref3) {
      var interaction = _ref3.interaction,
          event = _ref3.event;
    
      firePrepared(interaction, event, 'end');
    });
    
    function firePrepared(interaction, event, phase, preEnd) {
      var actionName = interaction.prepared.name;
    
      var newEvent = new InteractEvent(interaction, event, actionName, phase, interaction.element, null, preEnd);
    
      interaction.target.fire(newEvent);
      interaction.prevEvent = newEvent;
    }
    
    module.exports = actions;
    
    },{"../InteractEvent":3,"../Interaction":5}],7:[function(require,module,exports){
    'use strict';
    
    var actions = require('./base');
    var utils = require('../utils');
    var InteractEvent = require('../InteractEvent');
    /** @lends Interactable */
    var Interactable = require('../Interactable');
    var Interaction = require('../Interaction');
    var defaultOptions = require('../defaultOptions');
    
    var drag = {
      defaults: {
        enabled: false,
        mouseButtons: null,
    
        origin: null,
        snap: null,
        restrict: null,
        inertia: null,
        autoScroll: null,
    
        startAxis: 'xy',
        lockAxis: 'xy'
      },
    
      checker: function checker(pointer, event, interactable) {
        var dragOptions = interactable.options.drag;
    
        return dragOptions.enabled ? { name: 'drag', axis: dragOptions.lockAxis === 'start' ? dragOptions.startAxis : dragOptions.lockAxis } : null;
      },
    
      getCursor: function getCursor() {
        return 'move';
      }
    };
    
    Interaction.signals.on('before-action-move', function (_ref) {
      var interaction = _ref.interaction;
    
      if (interaction.prepared.name !== 'drag') {
        return;
      }
    
      var axis = interaction.prepared.axis;
    
      if (axis === 'x') {
        interaction.curCoords.page.y = interaction.startCoords.page.y;
        interaction.curCoords.client.y = interaction.startCoords.client.y;
    
        interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vx);
        interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vx);
        interaction.pointerDelta.client.vy = 0;
        interaction.pointerDelta.page.vy = 0;
      } else if (axis === 'y') {
        interaction.curCoords.page.x = interaction.startCoords.page.x;
        interaction.curCoords.client.x = interaction.startCoords.client.x;
    
        interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vy);
        interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vy);
        interaction.pointerDelta.client.vx = 0;
        interaction.pointerDelta.page.vx = 0;
      }
    });
    
    // dragmove
    InteractEvent.signals.on('new', function (_ref2) {
      var iEvent = _ref2.iEvent,
          interaction = _ref2.interaction;
    
      if (iEvent.type !== 'dragmove') {
        return;
      }
    
      var axis = interaction.prepared.axis;
    
      if (axis === 'x') {
        iEvent.pageY = interaction.startCoords.page.y;
        iEvent.clientY = interaction.startCoords.client.y;
        iEvent.dy = 0;
      } else if (axis === 'y') {
        iEvent.pageX = interaction.startCoords.page.x;
        iEvent.clientX = interaction.startCoords.client.x;
        iEvent.dx = 0;
      }
    });
    
    /**
     * ```js
     * interact(element).draggable({
     *     onstart: function (event) {},
     *     onmove : function (event) {},
     *     onend  : function (event) {},
     *
     *     // the axis in which the first movement must be
     *     // for the drag sequence to start
     *     // 'xy' by default - any direction
     *     startAxis: 'x' || 'y' || 'xy',
     *
     *     // 'xy' by default - don't restrict to one axis (move in any direction)
     *     // 'x' or 'y' to restrict movement to either axis
     *     // 'start' to restrict movement to the axis the drag started in
     *     lockAxis: 'x' || 'y' || 'xy' || 'start',
     *
     *     // max number of drags that can happen concurrently
     *     // with elements of this Interactable. Infinity by default
     *     max: Infinity,
     *
     *     // max number of drags that can target the same element+Interactable
     *     // 1 by default
     *     maxPerElement: 2
     * });
     *
     * var isDraggable = interact('element').draggable(); // true
     * ```
     *
     * Get or set whether drag actions can be performed on the target
     *
     * @param {boolean | object} [options] true/false or An object with event
     * listeners to be fired on drag events (object makes the Interactable
     * draggable)
     * @return {boolean | Interactable} boolean indicating if this can be the
     * target of drag events, or this Interctable
     */
    Interactable.prototype.draggable = function (options) {
      if (utils.is.object(options)) {
        this.options.drag.enabled = options.enabled === false ? false : true;
        this.setPerAction('drag', options);
        this.setOnEvents('drag', options);
    
        if (/^(xy|x|y|start)$/.test(options.lockAxis)) {
          this.options.drag.lockAxis = options.lockAxis;
        }
        if (/^(xy|x|y)$/.test(options.startAxis)) {
          this.options.drag.startAxis = options.startAxis;
        }
    
        return this;
      }
    
      if (utils.is.bool(options)) {
        this.options.drag.enabled = options;
    
        if (!options) {
          this.ondragstart = this.ondragstart = this.ondragend = null;
        }
    
        return this;
      }
    
      return this.options.drag;
    };
    
    actions.drag = drag;
    actions.names.push('drag');
    utils.merge(Interactable.eventTypes, ['dragstart', 'dragmove', 'draginertiastart', 'draginertiaresume', 'dragend']);
    actions.methodDict.drag = 'draggable';
    
    defaultOptions.drag = drag.defaults;
    
    module.exports = drag;
    
    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../utils":44,"./base":6}],8:[function(require,module,exports){
    'use strict';
    
    var actions = require('./base');
    var utils = require('../utils');
    var scope = require('../scope');
    /** @lends module:interact */
    var interact = require('../interact');
    var InteractEvent = require('../InteractEvent');
    /** @lends Interactable */
    var Interactable = require('../Interactable');
    var Interaction = require('../Interaction');
    var defaultOptions = require('../defaultOptions');
    
    var drop = {
      defaults: {
        enabled: false,
        accept: null,
        overlap: 'pointer'
      }
    };
    
    var dynamicDrop = false;
    
    Interaction.signals.on('action-start', function (_ref) {
      var interaction = _ref.interaction,
          event = _ref.event;
    
      if (interaction.prepared.name !== 'drag') {
        return;
      }
    
      // reset active dropzones
      interaction.activeDrops.dropzones = [];
      interaction.activeDrops.elements = [];
      interaction.activeDrops.rects = [];
    
      interaction.dropEvents = null;
    
      if (!interaction.dynamicDrop) {
        setActiveDrops(interaction.activeDrops, interaction.element);
      }
    
      var dragEvent = interaction.prevEvent;
      var dropEvents = getDropEvents(interaction, event, dragEvent);
    
      if (dropEvents.activate) {
        fireActiveDrops(interaction.activeDrops, dropEvents.activate);
      }
    });
    
    InteractEvent.signals.on('new', function (_ref2) {
      var interaction = _ref2.interaction,
          iEvent = _ref2.iEvent,
          event = _ref2.event;
    
      if (iEvent.type !== 'dragmove' && iEvent.type !== 'dragend') {
        return;
      }
    
      var draggableElement = interaction.element;
      var dragEvent = iEvent;
      var dropResult = getDrop(dragEvent, event, draggableElement);
    
      interaction.dropTarget = dropResult.dropzone;
      interaction.dropElement = dropResult.element;
    
      interaction.dropEvents = getDropEvents(interaction, event, dragEvent);
    });
    
    Interaction.signals.on('action-move', function (_ref3) {
      var interaction = _ref3.interaction;
    
      if (interaction.prepared.name !== 'drag') {
        return;
      }
    
      fireDropEvents(interaction, interaction.dropEvents);
    });
    
    Interaction.signals.on('action-end', function (_ref4) {
      var interaction = _ref4.interaction;
    
      if (interaction.prepared.name === 'drag') {
        fireDropEvents(interaction, interaction.dropEvents);
      }
    });
    
    Interaction.signals.on('stop-drag', function (_ref5) {
      var interaction = _ref5.interaction;
    
      interaction.activeDrops = {
        dropzones: null,
        elements: null,
        rects: null
      };
    
      interaction.dropEvents = null;
    });
    
    function collectDrops(activeDrops, element) {
      var drops = [];
      var elements = [];
    
      // collect all dropzones and their elements which qualify for a drop
      for (var _i = 0; _i < scope.interactables.length; _i++) {
        var _ref6;
    
        _ref6 = scope.interactables[_i];
        var current = _ref6;
    
        if (!current.options.drop.enabled) {
          continue;
        }
    
        var accept = current.options.drop.accept;
    
        // test the draggable element against the dropzone's accept setting
        if (utils.is.element(accept) && accept !== element || utils.is.string(accept) && !utils.matchesSelector(element, accept)) {
    
          continue;
        }
    
        // query for new elements if necessary
        var dropElements = utils.is.string(current.target) ? current._context.querySelectorAll(current.target) : [current.target];
    
        for (var _i2 = 0; _i2 < dropElements.length; _i2++) {
          var _ref7;
    
          _ref7 = dropElements[_i2];
          var currentElement = _ref7;
    
          if (currentElement !== element) {
            drops.push(current);
            elements.push(currentElement);
          }
        }
      }
    
      return {
        elements: elements,
        dropzones: drops
      };
    }
    
    function fireActiveDrops(activeDrops, event) {
      var prevElement = void 0;
    
      // loop through all active dropzones and trigger event
      for (var i = 0; i < activeDrops.dropzones.length; i++) {
        var current = activeDrops.dropzones[i];
        var currentElement = activeDrops.elements[i];
    
        // prevent trigger of duplicate events on same element
        if (currentElement !== prevElement) {
          // set current element as event target
          event.target = currentElement;
          current.fire(event);
        }
        prevElement = currentElement;
      }
    }
    
    // Collect a new set of possible drops and save them in activeDrops.
    // setActiveDrops should always be called when a drag has just started or a
    // drag event happens while dynamicDrop is true
    function setActiveDrops(activeDrops, dragElement) {
      // get dropzones and their elements that could receive the draggable
      var possibleDrops = collectDrops(activeDrops, dragElement);
    
      activeDrops.dropzones = possibleDrops.dropzones;
      activeDrops.elements = possibleDrops.elements;
      activeDrops.rects = [];
    
      for (var i = 0; i < activeDrops.dropzones.length; i++) {
        activeDrops.rects[i] = activeDrops.dropzones[i].getRect(activeDrops.elements[i]);
      }
    }
    
    function getDrop(dragEvent, event, dragElement) {
      var interaction = dragEvent.interaction;
      var validDrops = [];
    
      if (dynamicDrop) {
        setActiveDrops(interaction.activeDrops, dragElement);
      }
    
      // collect all dropzones and their elements which qualify for a drop
      for (var j = 0; j < interaction.activeDrops.dropzones.length; j++) {
        var current = interaction.activeDrops.dropzones[j];
        var currentElement = interaction.activeDrops.elements[j];
        var rect = interaction.activeDrops.rects[j];
    
        validDrops.push(current.dropCheck(dragEvent, event, interaction.target, dragElement, currentElement, rect) ? currentElement : null);
      }
    
      // get the most appropriate dropzone based on DOM depth and order
      var dropIndex = utils.indexOfDeepestElement(validDrops);
    
      return {
        dropzone: interaction.activeDrops.dropzones[dropIndex] || null,
        element: interaction.activeDrops.elements[dropIndex] || null
      };
    }
    
    function getDropEvents(interaction, pointerEvent, dragEvent) {
      var dropEvents = {
        enter: null,
        leave: null,
        activate: null,
        deactivate: null,
        move: null,
        drop: null
      };
    
      var tmpl = {
        dragEvent: dragEvent,
        interaction: interaction,
        target: interaction.dropElement,
        dropzone: interaction.dropTarget,
        relatedTarget: dragEvent.target,
        draggable: dragEvent.interactable,
        timeStamp: dragEvent.timeStamp
      };
    
      if (interaction.dropElement !== interaction.prevDropElement) {
        // if there was a prevDropTarget, create a dragleave event
        if (interaction.prevDropTarget) {
          dropEvents.leave = utils.extend({ type: 'dragleave' }, tmpl);
    
          dragEvent.dragLeave = dropEvents.leave.target = interaction.prevDropElement;
          dragEvent.prevDropzone = dropEvents.leave.dropzone = interaction.prevDropTarget;
        }
        // if the dropTarget is not null, create a dragenter event
        if (interaction.dropTarget) {
          dropEvents.enter = {
            dragEvent: dragEvent,
            interaction: interaction,
            target: interaction.dropElement,
            dropzone: interaction.dropTarget,
            relatedTarget: dragEvent.target,
            draggable: dragEvent.interactable,
            timeStamp: dragEvent.timeStamp,
            type: 'dragenter'
          };
    
          dragEvent.dragEnter = interaction.dropElement;
          dragEvent.dropzone = interaction.dropTarget;
        }
      }
    
      if (dragEvent.type === 'dragend' && interaction.dropTarget) {
        dropEvents.drop = utils.extend({ type: 'drop' }, tmpl);
    
        dragEvent.dropzone = interaction.dropTarget;
        dragEvent.relatedTarget = interaction.dropElement;
      }
      if (dragEvent.type === 'dragstart') {
        dropEvents.activate = utils.extend({ type: 'dropactivate' }, tmpl);
    
        dropEvents.activate.target = null;
        dropEvents.activate.dropzone = null;
      }
      if (dragEvent.type === 'dragend') {
        dropEvents.deactivate = utils.extend({ type: 'dropdeactivate' }, tmpl);
    
        dropEvents.deactivate.target = null;
        dropEvents.deactivate.dropzone = null;
      }
      if (dragEvent.type === 'dragmove' && interaction.dropTarget) {
        dropEvents.move = utils.extend({
          dragmove: dragEvent,
          type: 'dropmove'
        }, tmpl);
    
        dragEvent.dropzone = interaction.dropTarget;
      }
    
      return dropEvents;
    }
    
    function fireDropEvents(interaction, dropEvents) {
      var activeDrops = interaction.activeDrops,
          prevDropTarget = interaction.prevDropTarget,
          dropTarget = interaction.dropTarget,
          dropElement = interaction.dropElement;
    
    
      if (dropEvents.leave) {
        prevDropTarget.fire(dropEvents.leave);
      }
      if (dropEvents.move) {
        dropTarget.fire(dropEvents.move);
      }
      if (dropEvents.enter) {
        dropTarget.fire(dropEvents.enter);
      }
      if (dropEvents.drop) {
        dropTarget.fire(dropEvents.drop);
      }
      if (dropEvents.deactivate) {
        fireActiveDrops(activeDrops, dropEvents.deactivate);
      }
    
      interaction.prevDropTarget = dropTarget;
      interaction.prevDropElement = dropElement;
    }
    
    /**
     * ```js
     * interact(target)
     * .dropChecker(function(dragEvent,         // related dragmove or dragend event
     *                       event,             // TouchEvent/PointerEvent/MouseEvent
     *                       dropped,           // bool result of the default checker
     *                       dropzone,          // dropzone Interactable
     *                       dropElement,       // dropzone elemnt
     *                       draggable,         // draggable Interactable
     *                       draggableElement) {// draggable element
     *
     *   return dropped && event.target.hasAttribute('allow-drop');
     * }
     * ```
     *
     * ```js
     * interact('.drop').dropzone({
     *   accept: '.can-drop' || document.getElementById('single-drop'),
     *   overlap: 'pointer' || 'center' || zeroToOne
     * }
     * ```
     *
     * Returns or sets whether draggables can be dropped onto this target to
     * trigger drop events
     *
     * Dropzones can receive the following events:
     *  - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends
     *  - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone
     *  - `dragmove` when a draggable that has entered the dropzone is moved
     *  - `drop` when a draggable is dropped into this dropzone
     *
     * Use the `accept` option to allow only elements that match the given CSS
     * selector or element. The value can be:
     *
     *  - **an Element** - only that element can be dropped into this dropzone.
     *  - **a string**, - the element being dragged must match it as a CSS selector.
     *  - **`null`** - accept options is cleared - it accepts any element.
     *
     * Use the `overlap` option to set how drops are checked for. The allowed
     * values are:
     *
     *   - `'pointer'`, the pointer must be over the dropzone (default)
     *   - `'center'`, the draggable element's center must be over the dropzone
     *   - a number from 0-1 which is the `(intersection area) / (draggable area)`.
     *   e.g. `0.5` for drop to happen when half of the area of the draggable is
     *   over the dropzone
     *
     * Use the `checker` option to specify a function to check if a dragged element
     * is over this Interactable.
     *
     * @param {boolean | object | null} [options] The new options to be set.
     * @return {boolean | Interactable} The current setting or this Interactable
     */
    Interactable.prototype.dropzone = function (options) {
      if (utils.is.object(options)) {
        this.options.drop.enabled = options.enabled === false ? false : true;
    
        if (utils.is.function(options.ondrop)) {
          this.events.ondrop = options.ondrop;
        }
        if (utils.is.function(options.ondropactivate)) {
          this.events.ondropactivate = options.ondropactivate;
        }
        if (utils.is.function(options.ondropdeactivate)) {
          this.events.ondropdeactivate = options.ondropdeactivate;
        }
        if (utils.is.function(options.ondragenter)) {
          this.events.ondragenter = options.ondragenter;
        }
        if (utils.is.function(options.ondragleave)) {
          this.events.ondragleave = options.ondragleave;
        }
        if (utils.is.function(options.ondropmove)) {
          this.events.ondropmove = options.ondropmove;
        }
    
        if (/^(pointer|center)$/.test(options.overlap)) {
          this.options.drop.overlap = options.overlap;
        } else if (utils.is.number(options.overlap)) {
          this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);
        }
        if ('accept' in options) {
          this.options.drop.accept = options.accept;
        }
        if ('checker' in options) {
          this.options.drop.checker = options.checker;
        }
    
        return this;
      }
    
      if (utils.is.bool(options)) {
        this.options.drop.enabled = options;
    
        if (!options) {
          this.ondragenter = this.ondragleave = this.ondrop = this.ondropactivate = this.ondropdeactivate = null;
        }
    
        return this;
      }
    
      return this.options.drop;
    };
    
    Interactable.prototype.dropCheck = function (dragEvent, event, draggable, draggableElement, dropElement, rect) {
      var dropped = false;
    
      // if the dropzone has no rect (eg. display: none)
      // call the custom dropChecker or just return false
      if (!(rect = rect || this.getRect(dropElement))) {
        return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;
      }
    
      var dropOverlap = this.options.drop.overlap;
    
      if (dropOverlap === 'pointer') {
        var origin = utils.getOriginXY(draggable, draggableElement, 'drag');
        var page = utils.getPageXY(dragEvent);
    
        page.x += origin.x;
        page.y += origin.y;
    
        var horizontal = page.x > rect.left && page.x < rect.right;
        var vertical = page.y > rect.top && page.y < rect.bottom;
    
        dropped = horizontal && vertical;
      }
    
      var dragRect = draggable.getRect(draggableElement);
    
      if (dragRect && dropOverlap === 'center') {
        var cx = dragRect.left + dragRect.width / 2;
        var cy = dragRect.top + dragRect.height / 2;
    
        dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;
      }
    
      if (dragRect && utils.is.number(dropOverlap)) {
        var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top));
    
        var overlapRatio = overlapArea / (dragRect.width * dragRect.height);
    
        dropped = overlapRatio >= dropOverlap;
      }
    
      if (this.options.drop.checker) {
        dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);
      }
    
      return dropped;
    };
    
    Interactable.signals.on('unset', function (_ref8) {
      var interactable = _ref8.interactable;
    
      interactable.dropzone(false);
    });
    
    Interactable.settingsMethods.push('dropChecker');
    
    Interaction.signals.on('new', function (interaction) {
      interaction.dropTarget = null; // the dropzone a drag target might be dropped into
      interaction.dropElement = null; // the element at the time of checking
      interaction.prevDropTarget = null; // the dropzone that was recently dragged away from
      interaction.prevDropElement = null; // the element at the time of checking
      interaction.dropEvents = null; // the dropEvents related to the current drag event
    
      interaction.activeDrops = {
        dropzones: [], // the dropzones that are mentioned below
        elements: [], // elements of dropzones that accept the target draggable
        rects: [] // the rects of the elements mentioned above
      };
    });
    
    Interaction.signals.on('stop', function (_ref9) {
      var interaction = _ref9.interaction;
    
      interaction.dropTarget = interaction.dropElement = interaction.prevDropTarget = interaction.prevDropElement = null;
    });
    
    /**
     * Returns or sets whether the dimensions of dropzone elements are calculated
     * on every dragmove or only on dragstart for the default dropChecker
     *
     * @param {boolean} [newValue] True to check on each move. False to check only
     * before start
     * @return {boolean | interact} The current setting or interact
     */
    interact.dynamicDrop = function (newValue) {
      if (utils.is.bool(newValue)) {
        //if (dragging && dynamicDrop !== newValue && !newValue) {
        //calcRects(dropzones);
        //}
    
        dynamicDrop = newValue;
    
        return interact;
      }
      return dynamicDrop;
    };
    
    utils.merge(Interactable.eventTypes, ['dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop']);
    actions.methodDict.drop = 'dropzone';
    
    defaultOptions.drop = drop.defaults;
    
    module.exports = drop;
    
    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../interact":21,"../scope":33,"../utils":44,"./base":6}],9:[function(require,module,exports){
    'use strict';
    
    var actions = require('./base');
    var utils = require('../utils');
    var InteractEvent = require('../InteractEvent');
    var Interactable = require('../Interactable');
    var Interaction = require('../Interaction');
    var defaultOptions = require('../defaultOptions');
    
    var gesture = {
      defaults: {
        enabled: false,
        origin: null,
        restrict: null
      },
    
      checker: function checker(pointer, event, interactable, element, interaction) {
        if (interaction.pointerIds.length >= 2) {
          return { name: 'gesture' };
        }
    
        return null;
      },
    
      getCursor: function getCursor() {
        return '';
      }
    };
    
    InteractEvent.signals.on('new', function (_ref) {
      var iEvent = _ref.iEvent,
          interaction = _ref.interaction;
    
      if (iEvent.type !== 'gesturestart') {
        return;
      }
      iEvent.ds = 0;
    
      interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;
      interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;
      interaction.gesture.scale = 1;
    });
    
    InteractEvent.signals.on('new', function (_ref2) {
      var iEvent = _ref2.iEvent,
          interaction = _ref2.interaction;
    
      if (iEvent.type !== 'gesturemove') {
        return;
      }
    
      iEvent.ds = iEvent.scale - interaction.gesture.scale;
    
      interaction.target.fire(iEvent);
    
      interaction.gesture.prevAngle = iEvent.angle;
      interaction.gesture.prevDistance = iEvent.distance;
    
      if (iEvent.scale !== Infinity && iEvent.scale !== null && iEvent.scale !== undefined && !isNaN(iEvent.scale)) {
    
        interaction.gesture.scale = iEvent.scale;
      }
    });
    
    /**
     * ```js
     * interact(element).gesturable({
     *     onstart: function (event) {},
     *     onmove : function (event) {},
     *     onend  : function (event) {},
     *
     *     // limit multiple gestures.
     *     // See the explanation in {@link Interactable.draggable} example
     *     max: Infinity,
     *     maxPerElement: 1,
     * });
     *
     * var isGestureable = interact(element).gesturable();
     * ```
     *
     * Gets or sets whether multitouch gestures can be performed on the target
     *
     * @param {boolean | object} [options] true/false or An object with event
     * listeners to be fired on gesture events (makes the Interactable gesturable)
     * @return {boolean | Interactable} A boolean indicating if this can be the
     * target of gesture events, or this Interactable
     */
    Interactable.prototype.gesturable = function (options) {
      if (utils.is.object(options)) {
        this.options.gesture.enabled = options.enabled === false ? false : true;
        this.setPerAction('gesture', options);
        this.setOnEvents('gesture', options);
    
        return this;
      }
    
      if (utils.is.bool(options)) {
        this.options.gesture.enabled = options;
    
        if (!options) {
          this.ongesturestart = this.ongesturestart = this.ongestureend = null;
        }
    
        return this;
      }
    
      return this.options.gesture;
    };
    
    InteractEvent.signals.on('set-delta', function (_ref3) {
      var interaction = _ref3.interaction,
          iEvent = _ref3.iEvent,
          action = _ref3.action,
          event = _ref3.event,
          starting = _ref3.starting,
          ending = _ref3.ending,
          deltaSource = _ref3.deltaSource;
    
      if (action !== 'gesture') {
        return;
      }
    
      var pointers = interaction.pointers;
    
      iEvent.touches = [pointers[0], pointers[1]];
    
      if (starting) {
        iEvent.distance = utils.touchDistance(pointers, deltaSource);
        iEvent.box = utils.touchBBox(pointers);
        iEvent.scale = 1;
        iEvent.ds = 0;
        iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource);
        iEvent.da = 0;
      } else if (ending || event instanceof InteractEvent) {
        iEvent.distance = interaction.prevEvent.distance;
        iEvent.box = interaction.prevEvent.box;
        iEvent.scale = interaction.prevEvent.scale;
        iEvent.ds = iEvent.scale - 1;
        iEvent.angle = interaction.prevEvent.angle;
        iEvent.da = iEvent.angle - interaction.gesture.startAngle;
      } else {
        iEvent.distance = utils.touchDistance(pointers, deltaSource);
        iEvent.box = utils.touchBBox(pointers);
        iEvent.scale = iEvent.distance / interaction.gesture.startDistance;
        iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);
    
        iEvent.ds = iEvent.scale - interaction.gesture.prevScale;
        iEvent.da = iEvent.angle - interaction.gesture.prevAngle;
      }
    });
    
    Interaction.signals.on('new', function (interaction) {
      interaction.gesture = {
        start: { x: 0, y: 0 },
    
        startDistance: 0, // distance between two touches of touchStart
        prevDistance: 0,
        distance: 0,
    
        scale: 1, // gesture.distance / gesture.startDistance
    
        startAngle: 0, // angle of line joining two touches
        prevAngle: 0 // angle of the previous gesture event
      };
    });
    
    actions.gesture = gesture;
    actions.names.push('gesture');
    utils.merge(Interactable.eventTypes, ['gesturestart', 'gesturemove', 'gestureend']);
    actions.methodDict.gesture = 'gesturable';
    
    defaultOptions.gesture = gesture.defaults;
    
    module.exports = gesture;
    
    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../utils":44,"./base":6}],10:[function(require,module,exports){
    'use strict';
    
    var actions = require('./base');
    var utils = require('../utils');
    var browser = require('../utils/browser');
    var InteractEvent = require('../InteractEvent');
    /** @lends Interactable */
    var Interactable = require('../Interactable');
    var Interaction = require('../Interaction');
    var defaultOptions = require('../defaultOptions');
    
    // Less Precision with touch input
    var defaultMargin = browser.supportsTouch || browser.supportsPointerEvent ? 20 : 10;
    
    var resize = {
      defaults: {
        enabled: false,
        mouseButtons: null,
    
        origin: null,
        snap: null,
        restrict: null,
        inertia: null,
        autoScroll: null,
    
        square: false,
        preserveAspectRatio: false,
        axis: 'xy',
    
        // use default margin
        margin: NaN,
    
        // object with props left, right, top, bottom which are
        // true/false values to resize when the pointer is over that edge,
        // CSS selectors to match the handles for each direction
        // or the Elements for each handle
        edges: null,
    
        // a value of 'none' will limit the resize rect to a minimum of 0x0
        // 'negate' will alow the rect to have negative width/height
        // 'reposition' will keep the width/height positive by swapping
        // the top and bottom edges and/or swapping the left and right edges
        invert: 'none'
      },
    
      checker: function checker(pointer, event, interactable, element, interaction, rect) {
        if (!rect) {
          return null;
        }
    
        var page = utils.extend({}, interaction.curCoords.page);
        var options = interactable.options;
    
        if (options.resize.enabled) {
          var resizeOptions = options.resize;
          var resizeEdges = { left: false, right: false, top: false, bottom: false };
    
          // if using resize.edges
          if (utils.is.object(resizeOptions.edges)) {
            for (var edge in resizeEdges) {
              resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || defaultMargin);
            }
    
            resizeEdges.left = resizeEdges.left && !resizeEdges.right;
            resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;
    
            if (resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom) {
              return {
                name: 'resize',
                edges: resizeEdges
              };
            }
          } else {
            var right = options.resize.axis !== 'y' && page.x > rect.right - defaultMargin;
            var bottom = options.resize.axis !== 'x' && page.y > rect.bottom - defaultMargin;
    
            if (right || bottom) {
              return {
                name: 'resize',
                axes: (right ? 'x' : '') + (bottom ? 'y' : '')
              };
            }
          }
        }
    
        return null;
      },
    
      cursors: browser.isIe9 ? {
        x: 'e-resize',
        y: 's-resize',
        xy: 'se-resize',
    
        top: 'n-resize',
        left: 'w-resize',
        bottom: 's-resize',
        right: 'e-resize',
        topleft: 'se-resize',
        bottomright: 'se-resize',
        topright: 'ne-resize',
        bottomleft: 'ne-resize'
      } : {
        x: 'ew-resize',
        y: 'ns-resize',
        xy: 'nwse-resize',
    
        top: 'ns-resize',
        left: 'ew-resize',
        bottom: 'ns-resize',
        right: 'ew-resize',
        topleft: 'nwse-resize',
        bottomright: 'nwse-resize',
        topright: 'nesw-resize',
        bottomleft: 'nesw-resize'
      },
    
      getCursor: function getCursor(action) {
        if (action.axis) {
          return resize.cursors[action.name + action.axis];
        } else if (action.edges) {
          var cursorKey = '';
          var edgeNames = ['top', 'bottom', 'left', 'right'];
    
          for (var i = 0; i < 4; i++) {
            if (action.edges[edgeNames[i]]) {
              cursorKey += edgeNames[i];
            }
          }
    
          return resize.cursors[cursorKey];
        }
      }
    };
    
    // resizestart
    InteractEvent.signals.on('new', function (_ref) {
      var iEvent = _ref.iEvent,
          interaction = _ref.interaction;
    
      if (iEvent.type !== 'resizestart' || !interaction.prepared.edges) {
        return;
      }
    
      var startRect = interaction.target.getRect(interaction.element);
      var resizeOptions = interaction.target.options.resize;
    
      /*
       * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge
       * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make
       * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend
       * on the active edges and the edge being interacted with.
       */
      if (resizeOptions.square || resizeOptions.preserveAspectRatio) {
        var linkedEdges = utils.extend({}, interaction.prepared.edges);
    
        linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;
        linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;
        linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;
        linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;
    
        interaction.prepared._linkedEdges = linkedEdges;
      } else {
        interaction.prepared._linkedEdges = null;
      }
    
      // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize
      if (resizeOptions.preserveAspectRatio) {
        interaction.resizeStartAspectRatio = startRect.width / startRect.height;
      }
    
      interaction.resizeRects = {
        start: startRect,
        current: utils.extend({}, startRect),
        inverted: utils.extend({}, startRect),
        previous: utils.extend({}, startRect),
        delta: {
          left: 0, right: 0, width: 0,
          top: 0, bottom: 0, height: 0
        }
      };
    
      iEvent.rect = interaction.resizeRects.inverted;
      iEvent.deltaRect = interaction.resizeRects.delta;
    });
    
    // resizemove
    InteractEvent.signals.on('new', function (_ref2) {
      var iEvent = _ref2.iEvent,
          phase = _ref2.phase,
          interaction = _ref2.interaction;
    
      if (phase !== 'move' || !interaction.prepared.edges) {
        return;
      }
    
      var resizeOptions = interaction.target.options.resize;
      var invert = resizeOptions.invert;
      var invertible = invert === 'reposition' || invert === 'negate';
    
      var edges = interaction.prepared.edges;
    
      var start = interaction.resizeRects.start;
      var current = interaction.resizeRects.current;
      var inverted = interaction.resizeRects.inverted;
      var delta = interaction.resizeRects.delta;
      var previous = utils.extend(interaction.resizeRects.previous, inverted);
      var originalEdges = edges;
    
      var dx = iEvent.dx;
      var dy = iEvent.dy;
    
      if (resizeOptions.preserveAspectRatio || resizeOptions.square) {
        // `resize.preserveAspectRatio` takes precedence over `resize.square`
        var startAspectRatio = resizeOptions.preserveAspectRatio ? interaction.resizeStartAspectRatio : 1;
    
        edges = interaction.prepared._linkedEdges;
    
        if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {
          dy = -dx / startAspectRatio;
        } else if (originalEdges.left || originalEdges.right) {
          dy = dx / startAspectRatio;
        } else if (originalEdges.top || originalEdges.bottom) {
          dx = dy * startAspectRatio;
        }
      }
    
      // update the 'current' rect without modifications
      if (edges.top) {
        current.top += dy;
      }
      if (edges.bottom) {
        current.bottom += dy;
      }
      if (edges.left) {
        current.left += dx;
      }
      if (edges.right) {
        current.right += dx;
      }
    
      if (invertible) {
        // if invertible, copy the current rect
        utils.extend(inverted, current);
    
        if (invert === 'reposition') {
          // swap edge values if necessary to keep width/height positive
          var swap = void 0;
    
          if (inverted.top > inverted.bottom) {
            swap = inverted.top;
    
            inverted.top = inverted.bottom;
            inverted.bottom = swap;
          }
          if (inverted.left > inverted.right) {
            swap = inverted.left;
    
            inverted.left = inverted.right;
            inverted.right = swap;
          }
        }
      } else {
        // if not invertible, restrict to minimum of 0x0 rect
        inverted.top = Math.min(current.top, start.bottom);
        inverted.bottom = Math.max(current.bottom, start.top);
        inverted.left = Math.min(current.left, start.right);
        inverted.right = Math.max(current.right, start.left);
      }
    
      inverted.width = inverted.right - inverted.left;
      inverted.height = inverted.bottom - inverted.top;
    
      for (var edge in inverted) {
        delta[edge] = inverted[edge] - previous[edge];
      }
    
      iEvent.edges = interaction.prepared.edges;
      iEvent.rect = inverted;
      iEvent.deltaRect = delta;
    });
    
    /**
     * ```js
     * interact(element).resizable({
     *   onstart: function (event) {},
     *   onmove : function (event) {},
     *   onend  : function (event) {},
     *
     *   edges: {
     *     top   : true,       // Use pointer coords to check for resize.
     *     left  : false,      // Disable resizing from left edge.
     *     bottom: '.resize-s',// Resize if pointer target matches selector
     *     right : handleEl    // Resize if pointer target is the given Element
     *   },
     *
     *     // Width and height can be adjusted independently. When `true`, width and
     *     // height are adjusted at a 1:1 ratio.
     *     square: false,
     *
     *     // Width and height can be adjusted independently. When `true`, width and
     *     // height maintain the aspect ratio they had when resizing started.
     *     preserveAspectRatio: false,
     *
     *   // a value of 'none' will limit the resize rect to a minimum of 0x0
     *   // 'negate' will allow the rect to have negative width/height
     *   // 'reposition' will keep the width/height positive by swapping
     *   // the top and bottom edges and/or swapping the left and right edges
     *   invert: 'none' || 'negate' || 'reposition'
     *
     *   // limit multiple resizes.
     *   // See the explanation in the {@link Interactable.draggable} example
     *   max: Infinity,
     *   maxPerElement: 1,
     * });
     *
     * var isResizeable = interact(element).resizable();
     * ```
     *
     * Gets or sets whether resize actions can be performed on the target
     *
     * @param {boolean | object} [options] true/false or An object with event
     * listeners to be fired on resize events (object makes the Interactable
     * resizable)
     * @return {boolean | Interactable} A boolean indicating if this can be the
     * target of resize elements, or this Interactable
     */
    Interactable.prototype.resizable = function (options) {
      if (utils.is.object(options)) {
        this.options.resize.enabled = options.enabled === false ? false : true;
        this.setPerAction('resize', options);
        this.setOnEvents('resize', options);
    
        if (/^x$|^y$|^xy$/.test(options.axis)) {
          this.options.resize.axis = options.axis;
        } else if (options.axis === null) {
          this.options.resize.axis = defaultOptions.resize.axis;
        }
    
        if (utils.is.bool(options.preserveAspectRatio)) {
          this.options.resize.preserveAspectRatio = options.preserveAspectRatio;
        } else if (utils.is.bool(options.square)) {
          this.options.resize.square = options.square;
        }
    
        return this;
      }
      if (utils.is.bool(options)) {
        this.options.resize.enabled = options;
    
        if (!options) {
          this.onresizestart = this.onresizestart = this.onresizeend = null;
        }
    
        return this;
      }
      return this.options.resize;
    };
    
    function checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {
      // false, '', undefined, null
      if (!value) {
        return false;
      }
    
      // true value, use pointer coords and element rect
      if (value === true) {
        // if dimensions are negative, "switch" edges
        var width = utils.is.number(rect.width) ? rect.width : rect.right - rect.left;
        var height = utils.is.number(rect.height) ? rect.height : rect.bottom - rect.top;
    
        if (width < 0) {
          if (name === 'left') {
            name = 'right';
          } else if (name === 'right') {
            name = 'left';
          }
        }
        if (height < 0) {
          if (name === 'top') {
            name = 'bottom';
          } else if (name === 'bottom') {
            name = 'top';
          }
        }
    
        if (name === 'left') {
          return page.x < (width >= 0 ? rect.left : rect.right) + margin;
        }
        if (name === 'top') {
          return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;
        }
    
        if (name === 'right') {
          return page.x > (width >= 0 ? rect.right : rect.left) - margin;
        }
        if (name === 'bottom') {
          return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;
        }
      }
    
      // the remaining checks require an element
      if (!utils.is.element(element)) {
        return false;
      }
    
      return utils.is.element(value)
      // the value is an element to use as a resize handle
      ? value === element
      // otherwise check if element matches value as selector
      : utils.matchesUpTo(element, value, interactableElement);
    }
    
    Interaction.signals.on('new', function (interaction) {
      interaction.resizeAxes = 'xy';
    });
    
    InteractEvent.signals.on('set-delta', function (_ref3) {
      var interaction = _ref3.interaction,
          iEvent = _ref3.iEvent,
          action = _ref3.action;
    
      if (action !== 'resize' || !interaction.resizeAxes) {
        return;
      }
    
      var options = interaction.target.options;
    
      if (options.resize.square) {
        if (interaction.resizeAxes === 'y') {
          iEvent.dx = iEvent.dy;
        } else {
          iEvent.dy = iEvent.dx;
        }
        iEvent.axes = 'xy';
      } else {
        iEvent.axes = interaction.resizeAxes;
    
        if (interaction.resizeAxes === 'x') {
          iEvent.dy = 0;
        } else if (interaction.resizeAxes === 'y') {
          iEvent.dx = 0;
        }
      }
    });
    
    actions.resize = resize;
    actions.names.push('resize');
    utils.merge(Interactable.eventTypes, ['resizestart', 'resizemove', 'resizeinertiastart', 'resizeinertiaresume', 'resizeend']);
    actions.methodDict.resize = 'resizable';
    
    defaultOptions.resize = resize.defaults;
    
    module.exports = resize;
    
    },{"../InteractEvent":3,"../Interactable":4,"../Interaction":5,"../defaultOptions":18,"../utils":44,"../utils/browser":36,"./base":6}],11:[function(require,module,exports){
    'use strict';
    
    var raf = require('./utils/raf');
    var getWindow = require('./utils/window').getWindow;
    var is = require('./utils/is');
    var domUtils = require('./utils/domUtils');
    var Interaction = require('./Interaction');
    var defaultOptions = require('./defaultOptions');
    
    var autoScroll = {
      defaults: {
        enabled: false,
        container: null, // the item that is scrolled (Window or HTMLElement)
        margin: 60,
        speed: 300 // the scroll speed in pixels per second
      },
    
      interaction: null,
      i: null, // the handle returned by window.setInterval
      x: 0, y: 0, // Direction each pulse is to scroll in
    
      isScrolling: false,
      prevTime: 0,
    
      start: function start(interaction) {
        autoScroll.isScrolling = true;
        raf.cancel(autoScroll.i);
    
        autoScroll.interaction = interaction;
        autoScroll.prevTime = new Date().getTime();
        autoScroll.i = raf.request(autoScroll.scroll);
      },
    
      stop: function stop() {
        autoScroll.isScrolling = false;
        raf.cancel(autoScroll.i);
      },
    
      // scroll the window by the values in scroll.x/y
      scroll: function scroll() {
        var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll;
        var container = options.container || getWindow(autoScroll.interaction.element);
        var now = new Date().getTime();
        // change in time in seconds
        var dt = (now - autoScroll.prevTime) / 1000;
        // displacement
        var s = options.speed * dt;
    
        if (s >= 1) {
          if (is.window(container)) {
            container.scrollBy(autoScroll.x * s, autoScroll.y * s);
          } else if (container) {
            container.scrollLeft += autoScroll.x * s;
            container.scrollTop += autoScroll.y * s;
          }
    
          autoScroll.prevTime = now;
        }
    
        if (autoScroll.isScrolling) {
          raf.cancel(autoScroll.i);
          autoScroll.i = raf.request(autoScroll.scroll);
        }
      },
      check: function check(interactable, actionName) {
        var options = interactable.options;
    
        return options[actionName].autoScroll && options[actionName].autoScroll.enabled;
      },
      onInteractionMove: function onInteractionMove(_ref) {
        var interaction = _ref.interaction,
            pointer = _ref.pointer;
    
        if (!(interaction.interacting() && autoScroll.check(interaction.target, interaction.prepared.name))) {
          return;
        }
    
        if (interaction.simulation) {
          autoScroll.x = autoScroll.y = 0;
          return;
        }
    
        var top = void 0;
        var right = void 0;
        var bottom = void 0;
        var left = void 0;
    
        var options = interaction.target.options[interaction.prepared.name].autoScroll;
        var container = options.container || getWindow(interaction.element);
    
        if (is.window(container)) {
          left = pointer.clientX < autoScroll.margin;
          top = pointer.clientY < autoScroll.margin;
          right = pointer.clientX > container.innerWidth - autoScroll.margin;
          bottom = pointer.clientY > container.innerHeight - autoScroll.margin;
        } else {
          var rect = domUtils.getElementClientRect(container);
    
          left = pointer.clientX < rect.left + autoScroll.margin;
          top = pointer.clientY < rect.top + autoScroll.margin;
          right = pointer.clientX > rect.right - autoScroll.margin;
          bottom = pointer.clientY > rect.bottom - autoScroll.margin;
        }
    
        autoScroll.x = right ? 1 : left ? -1 : 0;
        autoScroll.y = bottom ? 1 : top ? -1 : 0;
    
        if (!autoScroll.isScrolling) {
          // set the autoScroll properties to those of the target
          autoScroll.margin = options.margin;
          autoScroll.speed = options.speed;
    
          autoScroll.start(interaction);
        }
      }
    };
    
    Interaction.signals.on('stop-active', function () {
      autoScroll.stop();
    });
    
    Interaction.signals.on('action-move', autoScroll.onInteractionMove);
    
    defaultOptions.perAction.autoScroll = autoScroll.defaults;
    
    module.exports = autoScroll;
    
    },{"./Interaction":5,"./defaultOptions":18,"./utils/domUtils":39,"./utils/is":46,"./utils/raf":50,"./utils/window":52}],12:[function(require,module,exports){
    'use strict';
    
    /** @lends Interactable */
    var Interactable = require('../Interactable');
    var actions = require('../actions/base');
    var is = require('../utils/is');
    var domUtils = require('../utils/domUtils');
    
    var _require = require('../utils'),
        warnOnce = _require.warnOnce;
    
    Interactable.prototype.getAction = function (pointer, event, interaction, element) {
      var action = this.defaultActionChecker(pointer, event, interaction, element);
    
      if (this.options.actionChecker) {
        return this.options.actionChecker(pointer, event, action, this, element, interaction);
      }
    
      return action;
    };
    
    /**
     * ```js
     * interact(element, { ignoreFrom: document.getElementById('no-action') });
     * // or
     * interact(element).ignoreFrom('input, textarea, a');
     * ```
     * @deprecated
     * If the target of the `mousedown`, `pointerdown` or `touchstart` event or any
     * of it's parents match the given CSS selector or Element, no
     * drag/resize/gesture is started.
     *
     * Don't use this method. Instead set the `ignoreFrom` option for each action
     * or for `pointerEvents`
     *
     * @example
     * interact(targett)
     *   .draggable({
     *     ignoreFrom: 'input, textarea, a[href]'',
     *   })
     *   .pointerEvents({
     *     ignoreFrom: '[no-pointer]',
     *   });
     *
     * @param {string | Element | null} [newValue] a CSS selector string, an
     * Element or `null` to not ignore any elements
     * @return {string | Element | object} The current ignoreFrom value or this
     * Interactable
     */
    Interactable.prototype.ignoreFrom = warnOnce(function (newValue) {
      return this._backCompatOption('ignoreFrom', newValue);
    }, 'Interactable.ignoreForm() has been deprecated. Use Interactble.draggable({ignoreFrom: newValue}).');
    
    /**
     * ```js
     *
     * @deprecated
     * A drag/resize/gesture is started only If the target of the `mousedown`,
     * `pointerdown` or `touchstart` event or any of it's parents match the given
     * CSS selector or Element.
     *
     * Don't use this method. Instead set the `allowFrom` option for each action
     * or for `pointerEvents`
     *
     * @example
     * interact(targett)
     *   .resizable({
     *     allowFrom: '.resize-handle',
     *   .pointerEvents({
     *     allowFrom: '.handle',,
     *   });
     *
     * @param {string | Element | null} [newValue] a CSS selector string, an
     * Element or `null` to allow from any element
     * @return {string | Element | object} The current allowFrom value or this
     * Interactable
     */
    Interactable.prototype.allowFrom = warnOnce(function (newValue) {
      return this._backCompatOption('allowFrom', newValue);
    }, 'Interactable.allowForm() has been deprecated. Use Interactble.draggable({allowFrom: newValue}).');
    
    Interactable.prototype.testIgnore = function (ignoreFrom, interactableElement, element) {
      if (!ignoreFrom || !is.element(element)) {
        return false;
      }
    
      if (is.string(ignoreFrom)) {
        return domUtils.matchesUpTo(element, ignoreFrom, interactableElement);
      } else if (is.element(ignoreFrom)) {
        return domUtils.nodeContains(ignoreFrom, element);
      }
    
      return false;
    };
    
    Interactable.prototype.testAllow = function (allowFrom, interactableElement, element) {
      if (!allowFrom) {
        return true;
      }
    
      if (!is.element(element)) {
        return false;
      }
    
      if (is.string(allowFrom)) {
        return domUtils.matchesUpTo(element, allowFrom, interactableElement);
      } else if (is.element(allowFrom)) {
        return domUtils.nodeContains(allowFrom, element);
      }
    
      return false;
    };
    
    Interactable.prototype.testIgnoreAllow = function (options, interactableElement, eventTarget) {
      return !this.testIgnore(options.ignoreFrom, interactableElement, eventTarget) && this.testAllow(options.allowFrom, interactableElement, eventTarget);
    };
    
    /**
     * ```js
     * interact('.resize-drag')
     *   .resizable(true)
     *   .draggable(true)
     *   .actionChecker(function (pointer, event, action, interactable, element, interaction) {
     *
     *   if (interact.matchesSelector(event.target, '.drag-handle') {
     *     // force drag with handle target
     *     action.name = drag;
     *   }
     *   else {
     *     // resize from the top and right edges
     *     action.name  = 'resize';
     *     action.edges = { top: true, right: true };
     *   }
     *
     *   return action;
     * });
     * ```
     *
     * Gets or sets the function used to check action to be performed on
     * pointerDown
     *
     * @param {function | null} [checker] A function which takes a pointer event,
     * defaultAction string, interactable, element and interaction as parameters
     * and returns an object with name property 'drag' 'resize' or 'gesture' and
     * optionally an `edges` object with boolean 'top', 'left', 'bottom' and right
     * props.
     * @return {Function | Interactable} The checker function or this Interactable
     */
    Interactable.prototype.actionChecker = function (checker) {
      if (is.function(checker)) {
        this.options.actionChecker = checker;
    
        return this;
      }
    
      if (checker === null) {
        delete this.options.actionChecker;
    
        return this;
      }
    
      return this.options.actionChecker;
    };
    
    /**
     * Returns or sets whether the the cursor should be changed depending on the
     * action that would be performed if the mouse were pressed and dragged.
     *
     * @param {boolean} [newValue]
     * @return {boolean | Interactable} The current setting or this Interactable
     */
    Interactable.prototype.styleCursor = function (newValue) {
      if (is.bool(newValue)) {
        this.options.styleCursor = newValue;
    
        return this;
      }
    
      if (newValue === null) {
        delete this.options.styleCursor;
    
        return this;
      }
    
      return this.options.styleCursor;
    };
    
    Interactable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {
      var rect = this.getRect(element);
      var buttons = event.buttons || {
        0: 1,
        1: 4,
        3: 8,
        4: 16
      }[event.button];
      var action = null;
    
      for (var _i = 0; _i < actions.names.length; _i++) {
        var _ref;
    
        _ref = actions.names[_i];
        var actionName = _ref;
    
        // check mouseButton setting if the pointer is down
        if (interaction.pointerIsDown && /mouse|pointer/.test(interaction.pointerType) && (buttons & this.options[actionName].mouseButtons) === 0) {
          continue;
        }
    
        action = actions[actionName].checker(pointer, event, this, element, interaction, rect);
    
        if (action) {
          return action;
        }
      }
    };
    
    },{"../Interactable":4,"../actions/base":6,"../utils":44,"../utils/domUtils":39,"../utils/is":46}],13:[function(require,module,exports){
    'use strict';
    
    var interact = require('../interact');
    var Interactable = require('../Interactable');
    var Interaction = require('../Interaction');
    var actions = require('../actions/base');
    var defaultOptions = require('../defaultOptions');
    var scope = require('../scope');
    var utils = require('../utils');
    var signals = require('../utils/Signals').new();
    
    require('./InteractableMethods');
    
    var autoStart = {
      signals: signals,
      withinInteractionLimit: withinInteractionLimit,
      // Allow this many interactions to happen simultaneously
      maxInteractions: Infinity,
      defaults: {
        perAction: {
          manualStart: false,
          max: Infinity,
          maxPerElement: 1,
          allowFrom: null,
          ignoreFrom: null,
    
          // only allow left button by default
          // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value
          mouseButtons: 1
        }
      },
      setActionDefaults: function setActionDefaults(action) {
        utils.extend(action.defaults, autoStart.defaults.perAction);
      },
      validateAction: validateAction
    };
    
    // set cursor style on mousedown
    Interaction.signals.on('down', function (_ref) {
      var interaction = _ref.interaction,
          pointer = _ref.pointer,
          event = _ref.event,
          eventTarget = _ref.eventTarget;
    
      if (interaction.interacting()) {
        return;
      }
    
      var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);
      prepare(interaction, actionInfo);
    });
    
    // set cursor style on mousemove
    Interaction.signals.on('move', function (_ref2) {
      var interaction = _ref2.interaction,
          pointer = _ref2.pointer,
          event = _ref2.event,
          eventTarget = _ref2.eventTarget;
    
      if (interaction.pointerType !== 'mouse' || interaction.pointerIsDown || interaction.interacting()) {
        return;
      }
    
      var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);
      prepare(interaction, actionInfo);
    });
    
    Interaction.signals.on('move', function (arg) {
      var interaction = arg.interaction,
          event = arg.event;
    
    
      if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) {
        return;
      }
    
      signals.fire('before-start', arg);
    
      var target = interaction.target;
    
      if (interaction.prepared.name && target) {
        // check manualStart and interaction limit
        if (target.options[interaction.prepared.name].manualStart || !withinInteractionLimit(target, interaction.element, interaction.prepared)) {
          interaction.stop(event);
        } else {
          interaction.start(interaction.prepared, target, interaction.element);
        }
      }
    });
    
    // Check if the current target supports the action.
    // If so, return the validated action. Otherwise, return null
    function validateAction(action, interactable, element, eventTarget) {
      if (utils.is.object(action) && interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) && interactable.options[action.name].enabled && withinInteractionLimit(interactable, element, action)) {
        return action;
      }
    
      return null;
    }
    
    function validateSelector(interaction, pointer, event, matches, matchElements, eventTarget) {
      for (var i = 0, len = matches.length; i < len; i++) {
        var match = matches[i];
        var matchElement = matchElements[i];
        var action = validateAction(match.getAction(pointer, event, interaction, matchElement), match, matchElement, eventTarget);
    
        if (action) {
          return {
            action: action,
            target: match,
            element: matchElement
          };
        }
      }
    
      return {};
    }
    
    function getActionInfo(interaction, pointer, event, eventTarget) {
      var matches = [];
      var matchElements = [];
    
      var element = eventTarget;
    
      function pushMatches(interactable) {
        matches.push(interactable);
        matchElements.push(element);
      }
    
      while (utils.is.element(element)) {
        matches = [];
        matchElements = [];
    
        scope.interactables.forEachMatch(element, pushMatches);
    
        var actionInfo = validateSelector(interaction, pointer, event, matches, matchElements, eventTarget);
    
        if (actionInfo.action && !actionInfo.target.options[actionInfo.action.name].manualStart) {
          return actionInfo;
        }
    
        element = utils.parentNode(element);
      }
    
      return {};
    }
    
    function prepare(interaction, _ref3) {
      var action = _ref3.action,
          target = _ref3.target,
          element = _ref3.element;
    
      action = action || {};
    
      if (interaction.target && interaction.target.options.styleCursor) {
        interaction.target._doc.documentElement.style.cursor = '';
      }
    
      interaction.target = target;
      interaction.element = element;
      utils.copyAction(interaction.prepared, action);
    
      if (target && target.options.styleCursor) {
        var cursor = action ? actions[action.name].getCursor(action) : '';
        interaction.target._doc.documentElement.style.cursor = cursor;
      }
    
      signals.fire('prepared', { interaction: interaction });
    }
    
    Interaction.signals.on('stop', function (_ref4) {
      var interaction = _ref4.interaction;
    
      var target = interaction.target;
    
      if (target && target.options.styleCursor) {
        target._doc.documentElement.style.cursor = '';
      }
    });
    
    function withinInteractionLimit(interactable, element, action) {
      var options = interactable.options;
      var maxActions = options[action.name].max;
      var maxPerElement = options[action.name].maxPerElement;
      var activeInteractions = 0;
      var targetCount = 0;
      var targetElementCount = 0;
    
      // no actions if any of these values == 0
      if (!(maxActions && maxPerElement && autoStart.maxInteractions)) {
        return;
      }
    
      for (var _i = 0; _i < scope.interactions.length; _i++) {
        var _ref5;
    
        _ref5 = scope.interactions[_i];
        var interaction = _ref5;
    
        var otherAction = interaction.prepared.name;
    
        if (!interaction.interacting()) {
          continue;
        }
    
        activeInteractions++;
    
        if (activeInteractions >= autoStart.maxInteractions) {
          return false;
        }
    
        if (interaction.target !== interactable) {
          continue;
        }
    
        targetCount += otherAction === action.name | 0;
    
        if (targetCount >= maxActions) {
          return false;
        }
    
        if (interaction.element === element) {
          targetElementCount++;
    
          if (otherAction !== action.name || targetElementCount >= maxPerElement) {
            return false;
          }
        }
      }
    
      return autoStart.maxInteractions > 0;
    }
    
    /**
     * Returns or sets the maximum number of concurrent interactions allowed.  By
     * default only 1 interaction is allowed at a time (for backwards
     * compatibility). To allow multiple interactions on the same Interactables and
     * elements, you need to enable it in the draggable, resizable and gesturable
     * `'max'` and `'maxPerElement'` options.
     *
     * @alias module:interact.maxInteractions
     *
     * @param {number} [newValue] Any number. newValue <= 0 means no interactions.
     */
    interact.maxInteractions = function (newValue) {
      if (utils.is.number(newValue)) {
        autoStart.maxInteractions = newValue;
    
        return interact;
      }
    
      return autoStart.maxInteractions;
    };
    
    Interactable.settingsMethods.push('styleCursor');
    Interactable.settingsMethods.push('actionChecker');
    Interactable.settingsMethods.push('ignoreFrom');
    Interactable.settingsMethods.push('allowFrom');
    
    defaultOptions.base.actionChecker = null;
    defaultOptions.base.styleCursor = true;
    
    utils.extend(defaultOptions.perAction, autoStart.defaults.perAction);
    
    module.exports = autoStart;
    
    },{"../Interactable":4,"../Interaction":5,"../actions/base":6,"../defaultOptions":18,"../interact":21,"../scope":33,"../utils":44,"../utils/Signals":34,"./InteractableMethods":12}],14:[function(require,module,exports){
    'use strict';
    
    var autoStart = require('./base');
    var scope = require('../scope');
    var is = require('../utils/is');
    
    var _require = require('../utils/domUtils'),
        parentNode = _require.parentNode;
    
    autoStart.setActionDefaults(require('../actions/drag'));
    
    autoStart.signals.on('before-start', function (_ref) {
      var interaction = _ref.interaction,
          eventTarget = _ref.eventTarget,
          dx = _ref.dx,
          dy = _ref.dy;
    
      if (interaction.prepared.name !== 'drag') {
        return;
      }
    
      // check if a drag is in the correct axis
      var absX = Math.abs(dx);
      var absY = Math.abs(dy);
      var targetOptions = interaction.target.options.drag;
      var startAxis = targetOptions.startAxis;
      var currentAxis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';
    
      interaction.prepared.axis = targetOptions.lockAxis === 'start' ? currentAxis[0] // always lock to one axis even if currentAxis === 'xy'
      : targetOptions.lockAxis;
    
      // if the movement isn't in the startAxis of the interactable
      if (currentAxis !== 'xy' && startAxis !== 'xy' && startAxis !== currentAxis) {
        // cancel the prepared action
        interaction.prepared.name = null;
    
        // then try to get a drag from another ineractable
        var element = eventTarget;
    
        var getDraggable = function getDraggable(interactable) {
          if (interactable === interaction.target) {
            return;
          }
    
          var options = interaction.target.options.drag;
    
          if (!options.manualStart && interactable.testIgnoreAllow(options, element, eventTarget)) {
    
            var action = interactable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);
    
            if (action && action.name === 'drag' && checkStartAxis(currentAxis, interactable) && autoStart.validateAction(action, interactable, element, eventTarget)) {
    
              return interactable;
            }
          }
        };
    
        // check all interactables
        while (is.element(element)) {
          var interactable = scope.interactables.forEachMatch(element, getDraggable);
    
          if (interactable) {
            interaction.prepared.name = 'drag';
            interaction.target = interactable;
            interaction.element = element;
            break;
          }
    
          element = parentNode(element);
        }
      }
    });
    
    function checkStartAxis(startAxis, interactable) {
      if (!interactable) {
        return false;
      }
    
      var thisAxis = interactable.options.drag.startAxis;
    
      return startAxis === 'xy' || thisAxis === 'xy' || thisAxis === startAxis;
    }
    
    },{"../actions/drag":7,"../scope":33,"../utils/domUtils":39,"../utils/is":46,"./base":13}],15:[function(require,module,exports){
    'use strict';
    
    require('./base').setActionDefaults(require('../actions/gesture'));
    
    },{"../actions/gesture":9,"./base":13}],16:[function(require,module,exports){
    'use strict';
    
    var autoStart = require('./base');
    var Interaction = require('../Interaction');
    
    autoStart.defaults.perAction.hold = 0;
    autoStart.defaults.perAction.delay = 0;
    
    Interaction.signals.on('new', function (interaction) {
      interaction.autoStartHoldTimer = null;
    });
    
    autoStart.signals.on('prepared', function (_ref) {
      var interaction = _ref.interaction;
    
      var hold = getHoldDuration(interaction);
    
      if (hold > 0) {
        interaction.autoStartHoldTimer = setTimeout(function () {
          interaction.start(interaction.prepared, interaction.target, interaction.element);
        }, hold);
      }
    });
    
    Interaction.signals.on('move', function (_ref2) {
      var interaction = _ref2.interaction,
          duplicate = _ref2.duplicate;
    
      if (interaction.pointerWasMoved && !duplicate) {
        clearTimeout(interaction.autoStartHoldTimer);
      }
    });
    
    // prevent regular down->move autoStart
    autoStart.signals.on('before-start', function (_ref3) {
      var interaction = _ref3.interaction;
    
      var hold = getHoldDuration(interaction);
    
      if (hold > 0) {
        interaction.prepared.name = null;
      }
    });
    
    function getHoldDuration(interaction) {
      var actionName = interaction.prepared && interaction.prepared.name;
    
      if (!actionName) {
        return null;
      }
    
      var options = interaction.target.options;
    
      return options[actionName].hold || options[actionName].delay;
    }
    
    module.exports = {
      getHoldDuration: getHoldDuration
    };
    
    },{"../Interaction":5,"./base":13}],17:[function(require,module,exports){
    'use strict';
    
    require('./base').setActionDefaults(require('../actions/resize'));
    
    },{"../actions/resize":10,"./base":13}],18:[function(require,module,exports){
    'use strict';
    
    module.exports = {
      base: {
        accept: null,
        preventDefault: 'auto',
        deltaSource: 'page'
      },
    
      perAction: {
        origin: { x: 0, y: 0 },
    
        inertia: {
          enabled: false,
          resistance: 10, // the lambda in exponential decay
          minSpeed: 100, // target speed must be above this for inertia to start
          endSpeed: 10, // the speed at which inertia is slow enough to stop
          allowResume: true, // allow resuming an action in inertia phase
          smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia
        }
      }
    };
    
    },{}],19:[function(require,module,exports){
    'use strict';
    
    /* browser entry point */
    
    // inertia
    require('./inertia');
    
    // modifiers
    require('./modifiers/snap');
    require('./modifiers/restrict');
    
    // pointerEvents
    require('./pointerEvents/base');
    require('./pointerEvents/holdRepeat');
    require('./pointerEvents/interactableTargets');
    
    // autoStart hold
    require('./autoStart/hold');
    
    // actions
    require('./actions/gesture');
    require('./actions/resize');
    require('./actions/drag');
    require('./actions/drop');
    
    // load these modifiers after resize is loaded
    require('./modifiers/snapSize');
    require('./modifiers/restrictEdges');
    require('./modifiers/restrictSize');
    
    // autoStart actions
    require('./autoStart/gesture');
    require('./autoStart/resize');
    require('./autoStart/drag');
    
    // Interactable preventDefault setting
    require('./interactablePreventDefault.js');
    
    // autoScroll
    require('./autoScroll');
    
    // export interact
    module.exports = require('./interact');
    
    },{"./actions/drag":7,"./actions/drop":8,"./actions/gesture":9,"./actions/resize":10,"./autoScroll":11,"./autoStart/drag":14,"./autoStart/gesture":15,"./autoStart/hold":16,"./autoStart/resize":17,"./inertia":20,"./interact":21,"./interactablePreventDefault.js":22,"./modifiers/restrict":24,"./modifiers/restrictEdges":25,"./modifiers/restrictSize":26,"./modifiers/snap":27,"./modifiers/snapSize":28,"./pointerEvents/base":30,"./pointerEvents/holdRepeat":31,"./pointerEvents/interactableTargets":32}],20:[function(require,module,exports){
    'use strict';
    
    var InteractEvent = require('./InteractEvent');
    var Interaction = require('./Interaction');
    var modifiers = require('./modifiers/base');
    var utils = require('./utils');
    var animationFrame = require('./utils/raf');
    
    Interaction.signals.on('new', function (interaction) {
      interaction.inertiaStatus = {
        active: false,
        smoothEnd: false,
        allowResume: false,
    
        startEvent: null,
        upCoords: {},
    
        xe: 0, ye: 0,
        sx: 0, sy: 0,
    
        t0: 0,
        vx0: 0, vys: 0,
        duration: 0,
    
        lambda_v0: 0,
        one_ve_v0: 0,
        i: null
      };
    
      interaction.boundInertiaFrame = function () {
        return inertiaFrame.apply(interaction);
      };
      interaction.boundSmoothEndFrame = function () {
        return smoothEndFrame.apply(interaction);
      };
    });
    
    Interaction.signals.on('down', function (_ref) {
      var interaction = _ref.interaction,
          event = _ref.event,
          pointer = _ref.pointer,
          eventTarget = _ref.eventTarget;
    
      var status = interaction.inertiaStatus;
    
      // Check if the down event hits the current inertia target
      if (status.active) {
        var element = eventTarget;
    
        // climb up the DOM tree from the event target
        while (utils.is.element(element)) {
    
          // if interaction element is the current inertia target element
          if (element === interaction.element) {
            // stop inertia
            animationFrame.cancel(status.i);
            status.active = false;
            interaction.simulation = null;
    
            // update pointers to the down event's coordinates
            interaction.updatePointer(pointer);
            utils.setCoords(interaction.curCoords, interaction.pointers);
    
            // fire appropriate signals
            var signalArg = { interaction: interaction };
            Interaction.signals.fire('before-action-move', signalArg);
            Interaction.signals.fire('action-resume', signalArg);
    
            // fire a reume event
            var resumeEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiaresume', interaction.element);
    
            interaction.target.fire(resumeEvent);
            interaction.prevEvent = resumeEvent;
            modifiers.resetStatuses(interaction.modifierStatuses);
    
            utils.copyCoords(interaction.prevCoords, interaction.curCoords);
            break;
          }
    
          element = utils.parentNode(element);
        }
      }
    });
    
    Interaction.signals.on('up', function (_ref2) {
      var interaction = _ref2.interaction,
          event = _ref2.event;
    
      var status = interaction.inertiaStatus;
    
      if (!interaction.interacting() || status.active) {
        return;
      }
    
      var target = interaction.target;
      var options = target && target.options;
      var inertiaOptions = options && interaction.prepared.name && options[interaction.prepared.name].inertia;
    
      var now = new Date().getTime();
      var statuses = {};
      var page = utils.extend({}, interaction.curCoords.page);
      var pointerSpeed = interaction.pointerDelta.client.speed;
    
      var smoothEnd = false;
      var modifierResult = void 0;
    
      // check if inertia should be started
      var inertiaPossible = inertiaOptions && inertiaOptions.enabled && interaction.prepared.name !== 'gesture' && event !== status.startEvent;
    
      var inertia = inertiaPossible && now - interaction.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;
    
      var modifierArg = {
        interaction: interaction,
        pageCoords: page,
        statuses: statuses,
        preEnd: true,
        requireEndOnly: true
      };
    
      // smoothEnd
      if (inertiaPossible && !inertia) {
        modifiers.resetStatuses(statuses);
    
        modifierResult = modifiers.setAll(modifierArg);
    
        if (modifierResult.shouldMove && modifierResult.locked) {
          smoothEnd = true;
        }
      }
    
      if (!(inertia || smoothEnd)) {
        return;
      }
    
      utils.copyCoords(status.upCoords, interaction.curCoords);
    
      interaction.pointers[0] = status.startEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiastart', interaction.element);
    
      status.t0 = now;
    
      status.active = true;
      status.allowResume = inertiaOptions.allowResume;
      interaction.simulation = status;
    
      target.fire(status.startEvent);
    
      if (inertia) {
        status.vx0 = interaction.pointerDelta.client.vx;
        status.vy0 = interaction.pointerDelta.client.vy;
        status.v0 = pointerSpeed;
    
        calcInertia(interaction, status);
    
        utils.extend(page, interaction.curCoords.page);
    
        page.x += status.xe;
        page.y += status.ye;
    
        modifiers.resetStatuses(statuses);
    
        modifierResult = modifiers.setAll(modifierArg);
    
        status.modifiedXe += modifierResult.dx;
        status.modifiedYe += modifierResult.dy;
    
        status.i = animationFrame.request(interaction.boundInertiaFrame);
      } else {
        status.smoothEnd = true;
        status.xe = modifierResult.dx;
        status.ye = modifierResult.dy;
    
        status.sx = status.sy = 0;
    
        status.i = animationFrame.request(interaction.boundSmoothEndFrame);
      }
    });
    
    Interaction.signals.on('stop-active', function (_ref3) {
      var interaction = _ref3.interaction;
    
      var status = interaction.inertiaStatus;
    
      if (status.active) {
        animationFrame.cancel(status.i);
        status.active = false;
        interaction.simulation = null;
      }
    });
    
    function calcInertia(interaction, status) {
      var inertiaOptions = interaction.target.options[interaction.prepared.name].inertia;
      var lambda = inertiaOptions.resistance;
      var inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;
    
      status.x0 = interaction.prevEvent.pageX;
      status.y0 = interaction.prevEvent.pageY;
      status.t0 = status.startEvent.timeStamp / 1000;
      status.sx = status.sy = 0;
    
      status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;
      status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;
      status.te = inertiaDur;
    
      status.lambda_v0 = lambda / status.v0;
      status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;
    }
    
    function inertiaFrame() {
      updateInertiaCoords(this);
      utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);
    
      var status = this.inertiaStatus;
      var options = this.target.options[this.prepared.name].inertia;
      var lambda = options.resistance;
      var t = new Date().getTime() / 1000 - status.t0;
    
      if (t < status.te) {
    
        var progress = 1 - (Math.exp(-lambda * t) - status.lambda_v0) / status.one_ve_v0;
    
        if (status.modifiedXe === status.xe && status.modifiedYe === status.ye) {
          status.sx = status.xe * progress;
          status.sy = status.ye * progress;
        } else {
          var quadPoint = utils.getQuadraticCurvePoint(0, 0, status.xe, status.ye, status.modifiedXe, status.modifiedYe, progress);
    
          status.sx = quadPoint.x;
          status.sy = quadPoint.y;
        }
    
        this.doMove();
    
        status.i = animationFrame.request(this.boundInertiaFrame);
      } else {
        status.sx = status.modifiedXe;
        status.sy = status.modifiedYe;
    
        this.doMove();
        this.end(status.startEvent);
        status.active = false;
        this.simulation = null;
      }
    
      utils.copyCoords(this.prevCoords, this.curCoords);
    }
    
    function smoothEndFrame() {
      updateInertiaCoords(this);
    
      var status = this.inertiaStatus;
      var t = new Date().getTime() - status.t0;
      var duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;
    
      if (t < duration) {
        status.sx = utils.easeOutQuad(t, 0, status.xe, duration);
        status.sy = utils.easeOutQuad(t, 0, status.ye, duration);
    
        this.pointerMove(status.startEvent, status.startEvent);
    
        status.i = animationFrame.request(this.boundSmoothEndFrame);
      } else {
        status.sx = status.xe;
        status.sy = status.ye;
    
        this.pointerMove(status.startEvent, status.startEvent);
        this.end(status.startEvent);
    
        status.smoothEnd = status.active = false;
        this.simulation = null;
      }
    }
    
    function updateInertiaCoords(interaction) {
      var status = interaction.inertiaStatus;
    
      // return if inertia isn't running
      if (!status.active) {
        return;
      }
    
      var pageUp = status.upCoords.page;
      var clientUp = status.upCoords.client;
    
      utils.setCoords(interaction.curCoords, [{
        pageX: pageUp.x + status.sx,
        pageY: pageUp.y + status.sy,
        clientX: clientUp.x + status.sx,
        clientY: clientUp.y + status.sy
      }]);
    }
    
    },{"./InteractEvent":3,"./Interaction":5,"./modifiers/base":23,"./utils":44,"./utils/raf":50}],21:[function(require,module,exports){
    'use strict';
    
    /** @module interact */
    
    var browser = require('./utils/browser');
    var events = require('./utils/events');
    var utils = require('./utils');
    var scope = require('./scope');
    var Interactable = require('./Interactable');
    var Interaction = require('./Interaction');
    
    var globalEvents = {};
    
    /**
     * ```js
     * interact('#draggable').draggable(true);
     *
     * var rectables = interact('rect');
     * rectables
     *   .gesturable(true)
     *   .on('gesturemove', function (event) {
     *       // ...
     *   });
     * ```
     *
     * The methods of this variable can be used to set elements as interactables
     * and also to change various default settings.
     *
     * Calling it as a function and passing an element or a valid CSS selector
     * string returns an Interactable object which has various methods to configure
     * it.
     *
     * @global
     *
     * @param {Element | string} element The HTML or SVG Element to interact with
     * or CSS selector
     * @return {Interactable}
     */
    function interact(element, options) {
      var interactable = scope.interactables.get(element, options);
    
      if (!interactable) {
        interactable = new Interactable(element, options);
        interactable.events.global = globalEvents;
      }
    
      return interactable;
    }
    
    /**
     * Check if an element or selector has been set with the {@link interact}
     * function
     *
     * @alias module:interact.isSet
     *
     * @param {Element} element The Element being searched for
     * @return {boolean} Indicates if the element or CSS selector was previously
     * passed to interact
    */
    interact.isSet = function (element, options) {
      return scope.interactables.indexOfElement(element, options && options.context) !== -1;
    };
    
    /**
     * Add a global listener for an InteractEvent or adds a DOM event to `document`
     *
     * @alias module:interact.on
     *
     * @param {string | array | object} type The types of events to listen for
     * @param {function} listener The function event (s)
     * @param {object | boolean} [options] object or useCapture flag for
     * addEventListener
     * @return {object} interact
     */
    interact.on = function (type, listener, options) {
      if (utils.is.string(type) && type.search(' ') !== -1) {
        type = type.trim().split(/ +/);
      }
    
      if (utils.is.array(type)) {
        for (var _i = 0; _i < type.length; _i++) {
          var _ref;
    
          _ref = type[_i];
          var eventType = _ref;
    
          interact.on(eventType, listener, options);
        }
    
        return interact;
      }
    
      if (utils.is.object(type)) {
        for (var prop in type) {
          interact.on(prop, type[prop], listener);
        }
    
        return interact;
      }
    
      // if it is an InteractEvent type, add listener to globalEvents
      if (utils.contains(Interactable.eventTypes, type)) {
        // if this type of event was never bound
        if (!globalEvents[type]) {
          globalEvents[type] = [listener];
        } else {
          globalEvents[type].push(listener);
        }
      }
      // If non InteractEvent type, addEventListener to document
      else {
          events.add(scope.document, type, listener, { options: options });
        }
    
      return interact;
    };
    
    /**
     * Removes a global InteractEvent listener or DOM event from `document`
     *
     * @alias module:interact.off
     *
     * @param {string | array | object} type The types of events that were listened
     * for
     * @param {function} listener The listener function to be removed
     * @param {object | boolean} options [options] object or useCapture flag for
     * removeEventListener
     * @return {object} interact
     */
    interact.off = function (type, listener, options) {
      if (utils.is.string(type) && type.search(' ') !== -1) {
        type = type.trim().split(/ +/);
      }
    
      if (utils.is.array(type)) {
        for (var _i2 = 0; _i2 < type.length; _i2++) {
          var _ref2;
    
          _ref2 = type[_i2];
          var eventType = _ref2;
    
          interact.off(eventType, listener, options);
        }
    
        return interact;
      }
    
      if (utils.is.object(type)) {
        for (var prop in type) {
          interact.off(prop, type[prop], listener);
        }
    
        return interact;
      }
    
      if (!utils.contains(Interactable.eventTypes, type)) {
        events.remove(scope.document, type, listener, options);
      } else {
        var index = void 0;
    
        if (type in globalEvents && (index = globalEvents[type].indexOf(listener)) !== -1) {
          globalEvents[type].splice(index, 1);
        }
      }
    
      return interact;
    };
    
    /**
     * Returns an object which exposes internal data
    
     * @alias module:interact.debug
     *
     * @return {object} An object with properties that outline the current state
     * and expose internal functions and variables
     */
    interact.debug = function () {
      return scope;
    };
    
    // expose the functions used to calculate multi-touch properties
    interact.getPointerAverage = utils.pointerAverage;
    interact.getTouchBBox = utils.touchBBox;
    interact.getTouchDistance = utils.touchDistance;
    interact.getTouchAngle = utils.touchAngle;
    
    interact.getElementRect = utils.getElementRect;
    interact.getElementClientRect = utils.getElementClientRect;
    interact.matchesSelector = utils.matchesSelector;
    interact.closest = utils.closest;
    
    /**
     * @alias module:interact.supportsTouch
     *
     * @return {boolean} Whether or not the browser supports touch input
     */
    interact.supportsTouch = function () {
      return browser.supportsTouch;
    };
    
    /**
     * @alias module:interact.supportsPointerEvent
     *
     * @return {boolean} Whether or not the browser supports PointerEvents
     */
    interact.supportsPointerEvent = function () {
      return browser.supportsPointerEvent;
    };
    
    /**
     * Cancels all interactions (end events are not fired)
     *
     * @alias module:interact.stop
     *
     * @param {Event} event An event on which to call preventDefault()
     * @return {object} interact
     */
    interact.stop = function (event) {
      for (var i = scope.interactions.length - 1; i >= 0; i--) {
        scope.interactions[i].stop(event);
      }
    
      return interact;
    };
    
    /**
     * Returns or sets the distance the pointer must be moved before an action
     * sequence occurs. This also affects tolerance for tap events.
     *
     * @alias module:interact.pointerMoveTolerance
     *
     * @param {number} [newValue] The movement from the start position must be greater than this value
     * @return {interact | number}
     */
    interact.pointerMoveTolerance = function (newValue) {
      if (utils.is.number(newValue)) {
        Interaction.pointerMoveTolerance = newValue;
    
        return interact;
      }
    
      return Interaction.pointerMoveTolerance;
    };
    
    interact.addDocument = scope.addDocument;
    interact.removeDocument = scope.removeDocument;
    
    scope.interact = interact;
    
    module.exports = interact;
    
    },{"./Interactable":4,"./Interaction":5,"./scope":33,"./utils":44,"./utils/browser":36,"./utils/events":40}],22:[function(require,module,exports){
    'use strict';
    
    var Interactable = require('./Interactable');
    var Interaction = require('./Interaction');
    var scope = require('./scope');
    var is = require('./utils/is');
    var events = require('./utils/events');
    var browser = require('./utils/browser');
    
    var _require = require('./utils/domUtils'),
        nodeContains = _require.nodeContains,
        matchesSelector = _require.matchesSelector;
    
    /**
     * Returns or sets whether to prevent the browser's default behaviour in
     * response to pointer events. Can be set to:
     *  - `'always'` to always prevent
     *  - `'never'` to never prevent
     *  - `'auto'` to let interact.js try to determine what would be best
     *
     * @param {string} [newValue] `true`, `false` or `'auto'`
     * @return {string | Interactable} The current setting or this Interactable
     */
    
    
    Interactable.prototype.preventDefault = function (newValue) {
      if (/^(always|never|auto)$/.test(newValue)) {
        this.options.preventDefault = newValue;
        return this;
      }
    
      if (is.bool(newValue)) {
        this.options.preventDefault = newValue ? 'always' : 'never';
        return this;
      }
    
      return this.options.preventDefault;
    };
    
    Interactable.prototype.checkAndPreventDefault = function (event) {
      var setting = this.options.preventDefault;
    
      if (setting === 'never') {
        return;
      }
    
      if (setting === 'always') {
        event.preventDefault();
        return;
      }
    
      // setting === 'auto'
    
      // don't preventDefault of touch{start,move} events if the browser supports passive
      // events listeners. CSS touch-action and user-selecct should be used instead
      if (events.supportsPassive && /^touch(start|move)$/.test(event.type) && !browser.isIOS) {
        return;
      }
    
      // don't preventDefault of pointerdown events
      if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {
        return;
      }
    
      // don't preventDefault on editable elements
      if (is.element(event.target) && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {
        return;
      }
    
      event.preventDefault();
    };
    
    function onInteractionEvent(_ref) {
      var interaction = _ref.interaction,
          event = _ref.event;
    
      if (interaction.target) {
        interaction.target.checkAndPreventDefault(event);
      }
    }
    
    var _arr = ['down', 'move', 'up', 'cancel'];
    for (var _i = 0; _i < _arr.length; _i++) {
      var eventSignal = _arr[_i];
      Interaction.signals.on(eventSignal, onInteractionEvent);
    }
    
    // prevent native HTML5 drag on interact.js target elements
    Interaction.docEvents.dragstart = function preventNativeDrag(event) {
      for (var _i2 = 0; _i2 < scope.interactions.length; _i2++) {
        var _ref2;
    
        _ref2 = scope.interactions[_i2];
        var interaction = _ref2;
    
    
        if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {
    
          interaction.target.checkAndPreventDefault(event);
          return;
        }
      }
    };
    
    },{"./Interactable":4,"./Interaction":5,"./scope":33,"./utils/browser":36,"./utils/domUtils":39,"./utils/events":40,"./utils/is":46}],23:[function(require,module,exports){
    'use strict';
    
    var InteractEvent = require('../InteractEvent');
    var Interaction = require('../Interaction');
    var extend = require('../utils/extend');
    
    var modifiers = {
      names: [],
    
      setOffsets: function setOffsets(arg) {
        var interaction = arg.interaction,
            page = arg.pageCoords;
        var target = interaction.target,
            element = interaction.element,
            startOffset = interaction.startOffset;
    
        var rect = target.getRect(element);
    
        if (rect) {
          startOffset.left = page.x - rect.left;
          startOffset.top = page.y - rect.top;
    
          startOffset.right = rect.right - page.x;
          startOffset.bottom = rect.bottom - page.y;
    
          if (!('width' in rect)) {
            rect.width = rect.right - rect.left;
          }
          if (!('height' in rect)) {
            rect.height = rect.bottom - rect.top;
          }
        } else {
          startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0;
        }
    
        arg.rect = rect;
        arg.interactable = target;
        arg.element = element;
    
        for (var _i = 0; _i < modifiers.names.length; _i++) {
          var _ref;
    
          _ref = modifiers.names[_i];
          var modifierName = _ref;
    
          arg.options = target.options[interaction.prepared.name][modifierName];
    
          if (!arg.options) {
            continue;
          }
    
          interaction.modifierOffsets[modifierName] = modifiers[modifierName].setOffset(arg);
        }
      },
    
      setAll: function setAll(arg) {
        var interaction = arg.interaction,
            statuses = arg.statuses,
            preEnd = arg.preEnd,
            requireEndOnly = arg.requireEndOnly;
    
        var result = {
          dx: 0,
          dy: 0,
          changed: false,
          locked: false,
          shouldMove: true
        };
    
        arg.modifiedCoords = extend({}, arg.pageCoords);
    
        for (var _i2 = 0; _i2 < modifiers.names.length; _i2++) {
          var _ref2;
    
          _ref2 = modifiers.names[_i2];
          var modifierName = _ref2;
    
          var modifier = modifiers[modifierName];
          var options = interaction.target.options[interaction.prepared.name][modifierName];
    
          if (!shouldDo(options, preEnd, requireEndOnly)) {
            continue;
          }
    
          arg.status = arg.status = statuses[modifierName];
          arg.options = options;
          arg.offset = arg.interaction.modifierOffsets[modifierName];
    
          modifier.set(arg);
    
          if (arg.status.locked) {
            arg.modifiedCoords.x += arg.status.dx;
            arg.modifiedCoords.y += arg.status.dy;
    
            result.dx += arg.status.dx;
            result.dy += arg.status.dy;
    
            result.locked = true;
          }
        }
    
        // a move should be fired if:
        //  - there are no modifiers enabled,
        //  - no modifiers are "locked" i.e. have changed the pointer's coordinates, or
        //  - the locked coords have changed since the last pointer move
        result.shouldMove = !arg.status || !result.locked || arg.status.changed;
    
        return result;
      },
    
      resetStatuses: function resetStatuses(statuses) {
        for (var _i3 = 0; _i3 < modifiers.names.length; _i3++) {
          var _ref3;
    
          _ref3 = modifiers.names[_i3];
          var modifierName = _ref3;
    
          var status = statuses[modifierName] || {};
    
          status.dx = status.dy = 0;
          status.modifiedX = status.modifiedY = NaN;
          status.locked = false;
          status.changed = true;
    
          statuses[modifierName] = status;
        }
    
        return statuses;
      },
    
      start: function start(_ref4, signalName) {
        var interaction = _ref4.interaction;
    
        var arg = {
          interaction: interaction,
          pageCoords: (signalName === 'action-resume' ? interaction.curCoords : interaction.startCoords).page,
          startOffset: interaction.startOffset,
          statuses: interaction.modifierStatuses,
          preEnd: false,
          requireEndOnly: false
        };
    
        modifiers.setOffsets(arg);
        modifiers.resetStatuses(arg.statuses);
    
        arg.pageCoords = extend({}, interaction.startCoords.page);
        interaction.modifierResult = modifiers.setAll(arg);
      },
    
      beforeMove: function beforeMove(_ref5) {
        var interaction = _ref5.interaction,
            preEnd = _ref5.preEnd,
            interactingBeforeMove = _ref5.interactingBeforeMove;
    
        var modifierResult = modifiers.setAll({
          interaction: interaction,
          preEnd: preEnd,
          pageCoords: interaction.curCoords.page,
          statuses: interaction.modifierStatuses,
          requireEndOnly: false
        });
    
        // don't fire an action move if a modifier would keep the event in the same
        // cordinates as before
        if (!modifierResult.shouldMove && interactingBeforeMove) {
          interaction._dontFireMove = true;
        }
    
        interaction.modifierResult = modifierResult;
      },
    
      end: function end(_ref6) {
        var interaction = _ref6.interaction,
            event = _ref6.event;
    
        for (var _i4 = 0; _i4 < modifiers.names.length; _i4++) {
          var _ref7;
    
          _ref7 = modifiers.names[_i4];
          var modifierName = _ref7;
    
          var options = interaction.target.options[interaction.prepared.name][modifierName];
    
          // if the endOnly option is true for any modifier
          if (shouldDo(options, true, true)) {
            // fire a move event at the modified coordinates
            interaction.doMove({ event: event, preEnd: true });
            break;
          }
        }
      },
    
      setXY: function setXY(arg) {
        var iEvent = arg.iEvent,
            interaction = arg.interaction;
    
        var modifierArg = extend({}, arg);
    
        for (var i = 0; i < modifiers.names.length; i++) {
          var modifierName = modifiers.names[i];
          modifierArg.options = interaction.target.options[interaction.prepared.name][modifierName];
    
          if (!modifierArg.options) {
            continue;
          }
    
          var modifier = modifiers[modifierName];
    
          modifierArg.status = interaction.modifierStatuses[modifierName];
    
          iEvent[modifierName] = modifier.modifyCoords(modifierArg);
        }
      }
    };
    
    Interaction.signals.on('new', function (interaction) {
      interaction.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };
      interaction.modifierOffsets = {};
      interaction.modifierStatuses = modifiers.resetStatuses({});
      interaction.modifierResult = null;
    });
    
    Interaction.signals.on('action-start', modifiers.start);
    Interaction.signals.on('action-resume', modifiers.start);
    Interaction.signals.on('before-action-move', modifiers.beforeMove);
    Interaction.signals.on('action-end', modifiers.end);
    
    InteractEvent.signals.on('set-xy', modifiers.setXY);
    
    function shouldDo(options, preEnd, requireEndOnly) {
      return options && options.enabled && (preEnd || !options.endOnly) && (!requireEndOnly || options.endOnly);
    }
    
    module.exports = modifiers;
    
    },{"../InteractEvent":3,"../Interaction":5,"../utils/extend":41}],24:[function(require,module,exports){
    'use strict';
    
    var modifiers = require('./base');
    var utils = require('../utils');
    var defaultOptions = require('../defaultOptions');
    
    var restrict = {
      defaults: {
        enabled: false,
        endOnly: false,
        restriction: null,
        elementRect: null
      },
    
      setOffset: function setOffset(_ref) {
        var rect = _ref.rect,
            startOffset = _ref.startOffset,
            options = _ref.options;
    
        var elementRect = options && options.elementRect;
        var offset = {};
    
        if (rect && elementRect) {
          offset.left = startOffset.left - rect.width * elementRect.left;
          offset.top = startOffset.top - rect.height * elementRect.top;
    
          offset.right = startOffset.right - rect.width * (1 - elementRect.right);
          offset.bottom = startOffset.bottom - rect.height * (1 - elementRect.bottom);
        } else {
          offset.left = offset.top = offset.right = offset.bottom = 0;
        }
    
        return offset;
      },
    
      set: function set(_ref2) {
        var modifiedCoords = _ref2.modifiedCoords,
            interaction = _ref2.interaction,
            status = _ref2.status,
            options = _ref2.options;
    
        if (!options) {
          return status;
        }
    
        var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, modifiedCoords);
    
        var restriction = getRestrictionRect(options.restriction, interaction, page);
    
        if (!restriction) {
          return status;
        }
    
        status.dx = 0;
        status.dy = 0;
        status.locked = false;
    
        var rect = restriction;
        var modifiedX = page.x;
        var modifiedY = page.y;
    
        var offset = interaction.modifierOffsets.restrict;
    
        // object is assumed to have
        // x, y, width, height or
        // left, top, right, bottom
        if ('x' in restriction && 'y' in restriction) {
          modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right, page.x), rect.x + offset.left);
          modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top);
        } else {
          modifiedX = Math.max(Math.min(rect.right - offset.right, page.x), rect.left + offset.left);
          modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top);
        }
    
        status.dx = modifiedX - page.x;
        status.dy = modifiedY - page.y;
    
        status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;
        status.locked = !!(status.dx || status.dy);
    
        status.modifiedX = modifiedX;
        status.modifiedY = modifiedY;
      },
    
      modifyCoords: function modifyCoords(_ref3) {
        var page = _ref3.page,
            client = _ref3.client,
            status = _ref3.status,
            phase = _ref3.phase,
            options = _ref3.options;
    
        var elementRect = options && options.elementRect;
    
        if (options && options.enabled && !(phase === 'start' && elementRect && status.locked)) {
    
          if (status.locked) {
            page.x += status.dx;
            page.y += status.dy;
            client.x += status.dx;
            client.y += status.dy;
    
            return {
              dx: status.dx,
              dy: status.dy
            };
          }
        }
      },
    
      getRestrictionRect: getRestrictionRect
    };
    
    function getRestrictionRect(value, interaction, page) {
      if (utils.is.function(value)) {
        return utils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]);
      } else {
        return utils.resolveRectLike(value, interaction.target, interaction.element);
      }
    }
    
    modifiers.restrict = restrict;
    modifiers.names.push('restrict');
    
    defaultOptions.perAction.restrict = restrict.defaults;
    
    module.exports = restrict;
    
    },{"../defaultOptions":18,"../utils":44,"./base":23}],25:[function(require,module,exports){
    'use strict';
    
    // This module adds the options.resize.restrictEdges setting which sets min and
    // max for the top, left, bottom and right edges of the target being resized.
    //
    // interact(target).resize({
    //   edges: { top: true, left: true },
    //   restrictEdges: {
    //     inner: { top: 200, left: 200, right: 400, bottom: 400 },
    //     outer: { top:   0, left:   0, right: 600, bottom: 600 },
    //   },
    // });
    
    var modifiers = require('./base');
    var utils = require('../utils');
    var rectUtils = require('../utils/rect');
    var defaultOptions = require('../defaultOptions');
    var resize = require('../actions/resize');
    
    var _require = require('./restrict'),
        getRestrictionRect = _require.getRestrictionRect;
    
    var noInner = { top: +Infinity, left: +Infinity, bottom: -Infinity, right: -Infinity };
    var noOuter = { top: -Infinity, left: -Infinity, bottom: +Infinity, right: +Infinity };
    
    var restrictEdges = {
      defaults: {
        enabled: false,
        endOnly: false,
        min: null,
        max: null,
        offset: null
      },
    
      setOffset: function setOffset(_ref) {
        var interaction = _ref.interaction,
            startOffset = _ref.startOffset,
            options = _ref.options;
    
        if (!options) {
          return utils.extend({}, startOffset);
        }
    
        var offset = getRestrictionRect(options.offset, interaction, interaction.startCoords.page);
    
        if (offset) {
          return {
            top: startOffset.top + offset.y,
            left: startOffset.left + offset.x,
            bottom: startOffset.bottom + offset.y,
            right: startOffset.right + offset.x
          };
        }
    
        return startOffset;
      },
    
      set: function set(_ref2) {
        var modifiedCoords = _ref2.modifiedCoords,
            interaction = _ref2.interaction,
            status = _ref2.status,
            offset = _ref2.offset,
            options = _ref2.options;
    
        var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;
    
        if (!interaction.interacting() || !edges) {
          return;
        }
    
        var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, modifiedCoords);
        var inner = rectUtils.xywhToTlbr(getRestrictionRect(options.inner, interaction, page)) || noInner;
        var outer = rectUtils.xywhToTlbr(getRestrictionRect(options.outer, interaction, page)) || noOuter;
    
        var modifiedX = page.x;
        var modifiedY = page.y;
    
        status.dx = 0;
        status.dy = 0;
        status.locked = false;
    
        if (edges.top) {
          modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);
        } else if (edges.bottom) {
          modifiedY = Math.max(Math.min(outer.bottom - offset.bottom, page.y), inner.bottom - offset.bottom);
        }
        if (edges.left) {
          modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);
        } else if (edges.right) {
          modifiedX = Math.max(Math.min(outer.right - offset.right, page.x), inner.right - offset.right);
        }
    
        status.dx = modifiedX - page.x;
        status.dy = modifiedY - page.y;
    
        status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;
        status.locked = !!(status.dx || status.dy);
    
        status.modifiedX = modifiedX;
        status.modifiedY = modifiedY;
      },
    
      modifyCoords: function modifyCoords(_ref3) {
        var page = _ref3.page,
            client = _ref3.client,
            status = _ref3.status,
            phase = _ref3.phase,
            options = _ref3.options;
    
        if (options && options.enabled && !(phase === 'start' && status.locked)) {
    
          if (status.locked) {
            page.x += status.dx;
            page.y += status.dy;
            client.x += status.dx;
            client.y += status.dy;
    
            return {
              dx: status.dx,
              dy: status.dy
            };
          }
        }
      },
    
      noInner: noInner,
      noOuter: noOuter,
      getRestrictionRect: getRestrictionRect
    };
    
    modifiers.restrictEdges = restrictEdges;
    modifiers.names.push('restrictEdges');
    
    defaultOptions.perAction.restrictEdges = restrictEdges.defaults;
    resize.defaults.restrictEdges = restrictEdges.defaults;
    
    module.exports = restrictEdges;
    
    },{"../actions/resize":10,"../defaultOptions":18,"../utils":44,"../utils/rect":51,"./base":23,"./restrict":24}],26:[function(require,module,exports){
    'use strict';
    
    // This module adds the options.resize.restrictSize setting which sets min and
    // max width and height for the target being resized.
    //
    // interact(target).resize({
    //   edges: { top: true, left: true },
    //   restrictSize: {
    //     min: { width: -600, height: -600 },
    //     max: { width:  600, height:  600 },
    //   },
    // });
    
    var modifiers = require('./base');
    var restrictEdges = require('./restrictEdges');
    var utils = require('../utils');
    var rectUtils = require('../utils/rect');
    var defaultOptions = require('../defaultOptions');
    var resize = require('../actions/resize');
    
    var noMin = { width: -Infinity, height: -Infinity };
    var noMax = { width: +Infinity, height: +Infinity };
    
    var restrictSize = {
      defaults: {
        enabled: false,
        endOnly: false,
        min: null,
        max: null
      },
    
      setOffset: function setOffset(_ref) {
        var interaction = _ref.interaction;
    
        return interaction.startOffset;
      },
    
      set: function set(arg) {
        var interaction = arg.interaction,
            options = arg.options;
    
        var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;
    
        if (!interaction.interacting() || !edges) {
          return;
        }
    
        var rect = rectUtils.xywhToTlbr(interaction.resizeRects.inverted);
    
        var minSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.min, interaction)) || noMin;
        var maxSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.max, interaction)) || noMax;
    
        arg.options = {
          enabled: options.enabled,
          endOnly: options.endOnly,
          inner: utils.extend({}, restrictEdges.noInner),
          outer: utils.extend({}, restrictEdges.noOuter)
        };
    
        if (edges.top) {
          arg.options.inner.top = rect.bottom - minSize.height;
          arg.options.outer.top = rect.bottom - maxSize.height;
        } else if (edges.bottom) {
          arg.options.inner.bottom = rect.top + minSize.height;
          arg.options.outer.bottom = rect.top + maxSize.height;
        }
        if (edges.left) {
          arg.options.inner.left = rect.right - minSize.width;
          arg.options.outer.left = rect.right - maxSize.width;
        } else if (edges.right) {
          arg.options.inner.right = rect.left + minSize.width;
          arg.options.outer.right = rect.left + maxSize.width;
        }
    
        restrictEdges.set(arg);
      },
    
      modifyCoords: restrictEdges.modifyCoords
    };
    
    modifiers.restrictSize = restrictSize;
    modifiers.names.push('restrictSize');
    
    defaultOptions.perAction.restrictSize = restrictSize.defaults;
    resize.defaults.restrictSize = restrictSize.defaults;
    
    module.exports = restrictSize;
    
    },{"../actions/resize":10,"../defaultOptions":18,"../utils":44,"../utils/rect":51,"./base":23,"./restrictEdges":25}],27:[function(require,module,exports){
    'use strict';
    
    var modifiers = require('./base');
    var interact = require('../interact');
    var utils = require('../utils');
    var defaultOptions = require('../defaultOptions');
    
    var snap = {
      defaults: {
        enabled: false,
        endOnly: false,
        range: Infinity,
        targets: null,
        offsets: null,
    
        relativePoints: null
      },
    
      setOffset: function setOffset(_ref) {
        var interaction = _ref.interaction,
            interactable = _ref.interactable,
            element = _ref.element,
            rect = _ref.rect,
            startOffset = _ref.startOffset,
            options = _ref.options;
    
        var offsets = [];
        var optionsOrigin = utils.rectToXY(utils.resolveRectLike(options.origin));
        var origin = optionsOrigin || utils.getOriginXY(interactable, element, interaction.prepared.name);
        options = options || interactable.options[interaction.prepared.name].snap || {};
    
        var snapOffset = void 0;
    
        if (options.offset === 'startCoords') {
          snapOffset = {
            x: interaction.startCoords.page.x - origin.x,
            y: interaction.startCoords.page.y - origin.y
          };
        } else {
          var offsetRect = utils.resolveRectLike(options.offset, interactable, element, [interaction]);
    
          snapOffset = utils.rectToXY(offsetRect) || { x: 0, y: 0 };
        }
    
        if (rect && options.relativePoints && options.relativePoints.length) {
          for (var _i = 0; _i < options.relativePoints.length; _i++) {
            var _ref3;
    
            _ref3 = options.relativePoints[_i];
            var _ref2 = _ref3;
            var relativeX = _ref2.x;
            var relativeY = _ref2.y;
    
            offsets.push({
              x: startOffset.left - rect.width * relativeX + snapOffset.x,
              y: startOffset.top - rect.height * relativeY + snapOffset.y
            });
          }
        } else {
          offsets.push(snapOffset);
        }
    
        return offsets;
      },
    
      set: function set(_ref4) {
        var interaction = _ref4.interaction,
            modifiedCoords = _ref4.modifiedCoords,
            status = _ref4.status,
            options = _ref4.options,
            offsets = _ref4.offset;
    
        var targets = [];
        var target = void 0;
        var page = void 0;
        var i = void 0;
    
        if (status.useStatusXY) {
          page = { x: status.x, y: status.y };
        } else {
          var origin = utils.getOriginXY(interaction.target, interaction.element, interaction.prepared.name);
    
          page = utils.extend({}, modifiedCoords);
    
          page.x -= origin.x;
          page.y -= origin.y;
        }
    
        status.realX = page.x;
        status.realY = page.y;
    
        var len = options.targets ? options.targets.length : 0;
    
        for (var _i2 = 0; _i2 < offsets.length; _i2++) {
          var _ref6;
    
          _ref6 = offsets[_i2];
          var _ref5 = _ref6;
          var offsetX = _ref5.x;
          var offsetY = _ref5.y;
    
          var relativeX = page.x - offsetX;
          var relativeY = page.y - offsetY;
    
          for (var _i3 = 0; _i3 < (options.targets || []).length; _i3++) {
            var _ref7;
    
            _ref7 = (options.targets || [])[_i3];
            var snapTarget = _ref7;
    
            if (utils.is.function(snapTarget)) {
              target = snapTarget(relativeX, relativeY, interaction);
            } else {
              target = snapTarget;
            }
    
            if (!target) {
              continue;
            }
    
            targets.push({
              x: utils.is.number(target.x) ? target.x + offsetX : relativeX,
              y: utils.is.number(target.y) ? target.y + offsetY : relativeY,
    
              range: utils.is.number(target.range) ? target.range : options.range
            });
          }
        }
    
        var closest = {
          target: null,
          inRange: false,
          distance: 0,
          range: 0,
          dx: 0,
          dy: 0
        };
    
        for (i = 0, len = targets.length; i < len; i++) {
          target = targets[i];
    
          var range = target.range;
          var dx = target.x - page.x;
          var dy = target.y - page.y;
          var distance = utils.hypot(dx, dy);
          var inRange = distance <= range;
    
          // Infinite targets count as being out of range
          // compared to non infinite ones that are in range
          if (range === Infinity && closest.inRange && closest.range !== Infinity) {
            inRange = false;
          }
    
          if (!closest.target || (inRange
          // is the closest target in range?
          ? closest.inRange && range !== Infinity
          // the pointer is relatively deeper in this target
          ? distance / range < closest.distance / closest.range
          // this target has Infinite range and the closest doesn't
          : range === Infinity && closest.range !== Infinity ||
          // OR this target is closer that the previous closest
          distance < closest.distance :
          // The other is not in range and the pointer is closer to this target
          !closest.inRange && distance < closest.distance)) {
    
            closest.target = target;
            closest.distance = distance;
            closest.range = range;
            closest.inRange = inRange;
            closest.dx = dx;
            closest.dy = dy;
    
            status.range = range;
          }
        }
    
        var snapChanged = void 0;
    
        if (closest.target) {
          snapChanged = status.modifiedX !== closest.target.x || status.modifiedY !== closest.target.y;
    
          status.modifiedX = closest.target.x;
          status.modifiedY = closest.target.y;
        } else {
          snapChanged = true;
    
          status.modifiedX = NaN;
          status.modifiedY = NaN;
        }
    
        status.dx = closest.dx;
        status.dy = closest.dy;
    
        status.changed = snapChanged || closest.inRange && !status.locked;
        status.locked = closest.inRange;
      },
    
      modifyCoords: function modifyCoords(_ref8) {
        var page = _ref8.page,
            client = _ref8.client,
            status = _ref8.status,
            phase = _ref8.phase,
            options = _ref8.options;
    
        var relativePoints = options && options.relativePoints;
    
        if (options && options.enabled && !(phase === 'start' && relativePoints && relativePoints.length)) {
    
          if (status.locked) {
            page.x += status.dx;
            page.y += status.dy;
            client.x += status.dx;
            client.y += status.dy;
          }
    
          return {
            range: status.range,
            locked: status.locked,
            x: status.modifiedX,
            y: status.modifiedY,
            realX: status.realX,
            realY: status.realY,
            dx: status.dx,
            dy: status.dy
          };
        }
      }
    };
    
    interact.createSnapGrid = function (grid) {
      return function (x, y) {
        var limits = grid.limits || {
          left: -Infinity,
          right: Infinity,
          top: -Infinity,
          bottom: Infinity
        };
        var offsetX = 0;
        var offsetY = 0;
    
        if (utils.is.object(grid.offset)) {
          offsetX = grid.offset.x;
          offsetY = grid.offset.y;
        }
    
        var gridx = Math.round((x - offsetX) / grid.x);
        var gridy = Math.round((y - offsetY) / grid.y);
    
        var newX = Math.max(limits.left, Math.min(limits.right, gridx * grid.x + offsetX));
        var newY = Math.max(limits.top, Math.min(limits.bottom, gridy * grid.y + offsetY));
    
        return {
          x: newX,
          y: newY,
          range: grid.range
        };
      };
    };
    
    modifiers.snap = snap;
    modifiers.names.push('snap');
    
    defaultOptions.perAction.snap = snap.defaults;
    
    module.exports = snap;
    
    },{"../defaultOptions":18,"../interact":21,"../utils":44,"./base":23}],28:[function(require,module,exports){
    'use strict';
    
    // This module allows snapping of the size of targets during resize
    // interactions.
    
    var modifiers = require('./base');
    var snap = require('./snap');
    var defaultOptions = require('../defaultOptions');
    var resize = require('../actions/resize');
    var utils = require('../utils/');
    
    var snapSize = {
      defaults: {
        enabled: false,
        endOnly: false,
        range: Infinity,
        targets: null,
        offsets: null
      },
    
      setOffset: function setOffset(arg) {
        var interaction = arg.interaction,
            options = arg.options;
    
        var edges = interaction.prepared.edges;
    
        if (!edges) {
          return;
        }
    
        arg.options = {
          relativePoints: [{
            x: edges.left ? 0 : 1,
            y: edges.top ? 0 : 1
          }],
          origin: { x: 0, y: 0 },
          offset: 'self',
          range: options.range
        };
    
        var offsets = snap.setOffset(arg);
        arg.options = options;
    
        return offsets;
      },
    
      set: function set(arg) {
        var interaction = arg.interaction,
            options = arg.options,
            offset = arg.offset,
            modifiedCoords = arg.modifiedCoords;
    
        var page = utils.extend({}, modifiedCoords);
        var relativeX = page.x - offset[0].x;
        var relativeY = page.y - offset[0].y;
    
        arg.options = utils.extend({}, options);
        arg.options.targets = [];
    
        for (var _i = 0; _i < (options.targets || []).length; _i++) {
          var _ref;
    
          _ref = (options.targets || [])[_i];
          var snapTarget = _ref;
    
          var target = void 0;
    
          if (utils.is.function(snapTarget)) {
            target = snapTarget(relativeX, relativeY, interaction);
          } else {
            target = snapTarget;
          }
    
          if (!target) {
            continue;
          }
    
          if ('width' in target && 'height' in target) {
            target.x = target.width;
            target.y = target.height;
          }
    
          arg.options.targets.push(target);
        }
    
        snap.set(arg);
      },
    
      modifyCoords: function modifyCoords(arg) {
        var options = arg.options;
    
    
        arg.options = utils.extend({}, options);
        arg.options.enabled = options.enabled;
        arg.options.relativePoints = [null];
    
        snap.modifyCoords(arg);
      }
    };
    
    modifiers.snapSize = snapSize;
    modifiers.names.push('snapSize');
    
    defaultOptions.perAction.snapSize = snapSize.defaults;
    resize.defaults.snapSize = snapSize.defaults;
    
    module.exports = snapSize;
    
    },{"../actions/resize":10,"../defaultOptions":18,"../utils/":44,"./base":23,"./snap":27}],29:[function(require,module,exports){
    'use strict';
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var pointerUtils = require('../utils/pointerUtils');
    
    module.exports = function () {
      /** */
      function PointerEvent(type, pointer, event, eventTarget, interaction) {
        _classCallCheck(this, PointerEvent);
    
        pointerUtils.pointerExtend(this, event);
    
        if (event !== pointer) {
          pointerUtils.pointerExtend(this, pointer);
        }
    
        this.interaction = interaction;
    
        this.timeStamp = new Date().getTime();
        this.originalEvent = event;
        this.type = type;
        this.pointerId = pointerUtils.getPointerId(pointer);
        this.pointerType = pointerUtils.getPointerType(pointer);
        this.target = eventTarget;
        this.currentTarget = null;
    
        if (type === 'tap') {
          var pointerIndex = interaction.getPointerIndex(pointer);
          this.dt = this.timeStamp - interaction.downTimes[pointerIndex];
    
          var interval = this.timeStamp - interaction.tapTime;
    
          this.double = !!(interaction.prevTap && interaction.prevTap.type !== 'doubletap' && interaction.prevTap.target === this.target && interval < 500);
        } else if (type === 'doubletap') {
          this.dt = pointer.timeStamp - interaction.tapTime;
        }
      }
    
      PointerEvent.prototype.subtractOrigin = function subtractOrigin(_ref) {
        var originX = _ref.x,
            originY = _ref.y;
    
        this.pageX -= originX;
        this.pageY -= originY;
        this.clientX -= originX;
        this.clientY -= originY;
    
        return this;
      };
    
      PointerEvent.prototype.addOrigin = function addOrigin(_ref2) {
        var originX = _ref2.x,
            originY = _ref2.y;
    
        this.pageX += originX;
        this.pageY += originY;
        this.clientX += originX;
        this.clientY += originY;
    
        return this;
      };
    
      /** */
    
    
      PointerEvent.prototype.preventDefault = function preventDefault() {
        this.originalEvent.preventDefault();
      };
    
      /** */
    
    
      PointerEvent.prototype.stopPropagation = function stopPropagation() {
        this.propagationStopped = true;
      };
    
      /** */
    
    
      PointerEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {
        this.immediatePropagationStopped = this.propagationStopped = true;
      };
    
      return PointerEvent;
    }();
    
    },{"../utils/pointerUtils":49}],30:[function(require,module,exports){
    'use strict';
    
    var PointerEvent = require('./PointerEvent');
    var Interaction = require('../Interaction');
    var utils = require('../utils');
    var defaults = require('../defaultOptions');
    var signals = require('../utils/Signals').new();
    
    var simpleSignals = ['down', 'up', 'cancel'];
    var simpleEvents = ['down', 'up', 'cancel'];
    
    var pointerEvents = {
      PointerEvent: PointerEvent,
      fire: fire,
      collectEventTargets: collectEventTargets,
      signals: signals,
      defaults: {
        holdDuration: 600,
        ignoreFrom: null,
        allowFrom: null,
        origin: { x: 0, y: 0 }
      },
      types: ['down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold']
    };
    
    function fire(arg) {
      var interaction = arg.interaction,
          pointer = arg.pointer,
          event = arg.event,
          eventTarget = arg.eventTarget,
          _arg$type = arg.type,
          type = _arg$type === undefined ? arg.pointerEvent.type : _arg$type,
          _arg$targets = arg.targets,
          targets = _arg$targets === undefined ? collectEventTargets(arg) : _arg$targets,
          _arg$pointerEvent = arg.pointerEvent,
          pointerEvent = _arg$pointerEvent === undefined ? new PointerEvent(type, pointer, event, eventTarget, interaction) : _arg$pointerEvent;
    
    
      var signalArg = {
        interaction: interaction,
        pointer: pointer,
        event: event,
        eventTarget: eventTarget,
        targets: targets,
        type: type,
        pointerEvent: pointerEvent
      };
    
      for (var i = 0; i < targets.length; i++) {
        var target = targets[i];
    
        for (var prop in target.props || {}) {
          pointerEvent[prop] = target.props[prop];
        }
    
        var origin = utils.getOriginXY(target.eventable, target.element);
    
        pointerEvent.subtractOrigin(origin);
        pointerEvent.eventable = target.eventable;
        pointerEvent.currentTarget = target.element;
    
        target.eventable.fire(pointerEvent);
    
        pointerEvent.addOrigin(origin);
    
        if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && i + 1 < targets.length && targets[i + 1].element !== pointerEvent.currentTarget) {
          break;
        }
      }
    
      signals.fire('fired', signalArg);
    
      if (type === 'tap') {
        // if pointerEvent should make a double tap, create and fire a doubletap
        // PointerEvent and use that as the prevTap
        var prevTap = pointerEvent.double ? fire({
          interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,
          type: 'doubletap'
        }) : pointerEvent;
    
        interaction.prevTap = prevTap;
        interaction.tapTime = prevTap.timeStamp;
      }
    
      return pointerEvent;
    }
    
    function collectEventTargets(_ref) {
      var interaction = _ref.interaction,
          pointer = _ref.pointer,
          event = _ref.event,
          eventTarget = _ref.eventTarget,
          type = _ref.type;
    
      var pointerIndex = interaction.getPointerIndex(pointer);
    
      // do not fire a tap event if the pointer was moved before being lifted
      if (type === 'tap' && (interaction.pointerWasMoved
      // or if the pointerup target is different to the pointerdown target
      || !(interaction.downTargets[pointerIndex] && interaction.downTargets[pointerIndex] === eventTarget))) {
        return [];
      }
    
      var path = utils.getPath(eventTarget);
      var signalArg = {
        interaction: interaction,
        pointer: pointer,
        event: event,
        eventTarget: eventTarget,
        type: type,
        path: path,
        targets: [],
        element: null
      };
    
      for (var _i = 0; _i < path.length; _i++) {
        var _ref2;
    
        _ref2 = path[_i];
        var element = _ref2;
    
        signalArg.element = element;
    
        signals.fire('collect-targets', signalArg);
      }
    
      if (type === 'hold') {
        signalArg.targets = signalArg.targets.filter(function (target) {
          return target.eventable.options.holdDuration === interaction.holdTimers[pointerIndex].duration;
        });
      }
    
      return signalArg.targets;
    }
    
    Interaction.signals.on('update-pointer-down', function (_ref3) {
      var interaction = _ref3.interaction,
          pointerIndex = _ref3.pointerIndex;
    
      interaction.holdTimers[pointerIndex] = { duration: Infinity, timeout: null };
    });
    
    Interaction.signals.on('remove-pointer', function (_ref4) {
      var interaction = _ref4.interaction,
          pointerIndex = _ref4.pointerIndex;
    
      interaction.holdTimers.splice(pointerIndex, 1);
    });
    
    Interaction.signals.on('move', function (_ref5) {
      var interaction = _ref5.interaction,
          pointer = _ref5.pointer,
          event = _ref5.event,
          eventTarget = _ref5.eventTarget,
          duplicateMove = _ref5.duplicateMove;
    
      var pointerIndex = interaction.getPointerIndex(pointer);
    
      if (!duplicateMove && (!interaction.pointerIsDown || interaction.pointerWasMoved)) {
        if (interaction.pointerIsDown) {
          clearTimeout(interaction.holdTimers[pointerIndex].timeout);
        }
    
        fire({
          interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,
          type: 'move'
        });
      }
    });
    
    Interaction.signals.on('down', function (_ref6) {
      var interaction = _ref6.interaction,
          pointer = _ref6.pointer,
          event = _ref6.event,
          eventTarget = _ref6.eventTarget,
          pointerIndex = _ref6.pointerIndex;
    
      var timer = interaction.holdTimers[pointerIndex];
      var path = utils.getPath(eventTarget);
      var signalArg = {
        interaction: interaction,
        pointer: pointer,
        event: event,
        eventTarget: eventTarget,
        type: 'hold',
        targets: [],
        path: path,
        element: null
      };
    
      for (var _i2 = 0; _i2 < path.length; _i2++) {
        var _ref7;
    
        _ref7 = path[_i2];
        var element = _ref7;
    
        signalArg.element = element;
    
        signals.fire('collect-targets', signalArg);
      }
    
      if (!signalArg.targets.length) {
        return;
      }
    
      var minDuration = Infinity;
    
      for (var _i3 = 0; _i3 < signalArg.targets.length; _i3++) {
        var _ref8;
    
        _ref8 = signalArg.targets[_i3];
        var target = _ref8;
    
        var holdDuration = target.eventable.options.holdDuration;
    
        if (holdDuration < minDuration) {
          minDuration = holdDuration;
        }
      }
    
      timer.duration = minDuration;
      timer.timeout = setTimeout(function () {
        fire({
          interaction: interaction,
          eventTarget: eventTarget,
          pointer: pointer,
          event: event,
          type: 'hold'
        });
      }, minDuration);
    });
    
    Interaction.signals.on('up', function (_ref9) {
      var interaction = _ref9.interaction,
          pointer = _ref9.pointer,
          event = _ref9.event,
          eventTarget = _ref9.eventTarget;
    
      if (!interaction.pointerWasMoved) {
        fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: 'tap' });
      }
    });
    
    var _arr = ['up', 'cancel'];
    for (var _i4 = 0; _i4 < _arr.length; _i4++) {
      var signalName = _arr[_i4];
      Interaction.signals.on(signalName, function (_ref11) {
        var interaction = _ref11.interaction,
            pointerIndex = _ref11.pointerIndex;
    
        if (interaction.holdTimers[pointerIndex]) {
          clearTimeout(interaction.holdTimers[pointerIndex].timeout);
        }
      });
    }
    
    function createSignalListener(type) {
      return function (_ref10) {
        var interaction = _ref10.interaction,
            pointer = _ref10.pointer,
            event = _ref10.event,
            eventTarget = _ref10.eventTarget;
    
        fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: type });
      };
    }
    
    for (var i = 0; i < simpleSignals.length; i++) {
      Interaction.signals.on(simpleSignals[i], createSignalListener(simpleEvents[i]));
    }
    
    Interaction.signals.on('new', function (interaction) {
      interaction.prevTap = null; // the most recent tap event on this interaction
      interaction.tapTime = 0; // time of the most recent tap event
      interaction.holdTimers = []; // [{ duration, timeout }]
    });
    
    defaults.pointerEvents = pointerEvents.defaults;
    module.exports = pointerEvents;
    
    },{"../Interaction":5,"../defaultOptions":18,"../utils":44,"../utils/Signals":34,"./PointerEvent":29}],31:[function(require,module,exports){
    'use strict';
    
    var pointerEvents = require('./base');
    var Interaction = require('../Interaction');
    
    pointerEvents.signals.on('new', onNew);
    pointerEvents.signals.on('fired', onFired);
    
    var _arr = ['move', 'up', 'cancel', 'endall'];
    for (var _i = 0; _i < _arr.length; _i++) {
      var signal = _arr[_i];
      Interaction.signals.on(signal, endHoldRepeat);
    }
    
    function onNew(_ref) {
      var pointerEvent = _ref.pointerEvent;
    
      if (pointerEvent.type !== 'hold') {
        return;
      }
    
      pointerEvent.count = (pointerEvent.count || 0) + 1;
    }
    
    function onFired(_ref2) {
      var interaction = _ref2.interaction,
          pointerEvent = _ref2.pointerEvent,
          eventTarget = _ref2.eventTarget,
          targets = _ref2.targets;
    
      if (pointerEvent.type !== 'hold' || !targets.length) {
        return;
      }
    
      // get the repeat interval from the first eventable
      var interval = targets[0].eventable.options.holdRepeatInterval;
    
      // don't repeat if the interval is 0 or less
      if (interval <= 0) {
        return;
      }
    
      // set a timeout to fire the holdrepeat event
      interaction.holdIntervalHandle = setTimeout(function () {
        pointerEvents.fire({
          interaction: interaction,
          eventTarget: eventTarget,
          type: 'hold',
          pointer: pointerEvent,
          event: pointerEvent
        });
      }, interval);
    }
    
    function endHoldRepeat(_ref3) {
      var interaction = _ref3.interaction;
    
      // set the interaction's holdStopTime property
      // to stop further holdRepeat events
      if (interaction.holdIntervalHandle) {
        clearInterval(interaction.holdIntervalHandle);
        interaction.holdIntervalHandle = null;
      }
    }
    
    // don't repeat by default
    pointerEvents.defaults.holdRepeatInterval = 0;
    pointerEvents.types.push('holdrepeat');
    
    module.exports = {
      onNew: onNew,
      onFired: onFired,
      endHoldRepeat: endHoldRepeat
    };
    
    },{"../Interaction":5,"./base":30}],32:[function(require,module,exports){
    'use strict';
    
    var pointerEvents = require('./base');
    var Interactable = require('../Interactable');
    var is = require('../utils/is');
    var scope = require('../scope');
    var extend = require('../utils/extend');
    
    var _require = require('../utils/arr'),
        merge = _require.merge;
    
    pointerEvents.signals.on('collect-targets', function (_ref) {
      var targets = _ref.targets,
          element = _ref.element,
          type = _ref.type,
          eventTarget = _ref.eventTarget;
    
      scope.interactables.forEachMatch(element, function (interactable) {
        var eventable = interactable.events;
        var options = eventable.options;
    
        if (eventable[type] && is.element(element) && interactable.testIgnoreAllow(options, element, eventTarget)) {
    
          targets.push({
            element: element,
            eventable: eventable,
            props: { interactable: interactable }
          });
        }
      });
    });
    
    Interactable.signals.on('new', function (_ref2) {
      var interactable = _ref2.interactable;
    
      interactable.events.getRect = function (element) {
        return interactable.getRect(element);
      };
    });
    
    Interactable.signals.on('set', function (_ref3) {
      var interactable = _ref3.interactable,
          options = _ref3.options;
    
      extend(interactable.events.options, pointerEvents.defaults);
      extend(interactable.events.options, options);
    });
    
    merge(Interactable.eventTypes, pointerEvents.types);
    
    Interactable.prototype.pointerEvents = function (options) {
      extend(this.events.options, options);
    
      return this;
    };
    
    var __backCompatOption = Interactable.prototype._backCompatOption;
    
    Interactable.prototype._backCompatOption = function (optionName, newValue) {
      var ret = __backCompatOption.call(this, optionName, newValue);
    
      if (ret === this) {
        this.events.options[optionName] = newValue;
      }
    
      return ret;
    };
    
    Interactable.settingsMethods.push('pointerEvents');
    
    },{"../Interactable":4,"../scope":33,"../utils/arr":35,"../utils/extend":41,"../utils/is":46,"./base":30}],33:[function(require,module,exports){
    'use strict';
    
    var utils = require('./utils');
    var events = require('./utils/events');
    var signals = require('./utils/Signals').new();
    
    var _require = require('./utils/window'),
        getWindow = _require.getWindow;
    
    var scope = {
      signals: signals,
      events: events,
      utils: utils,
    
      // main document
      document: require('./utils/domObjects').document,
      // all documents being listened to
      documents: [],
    
      addDocument: function addDocument(doc, win) {
        // do nothing if document is already known
        if (utils.contains(scope.documents, doc)) {
          return false;
        }
    
        win = win || getWindow(doc);
    
        scope.documents.push(doc);
        events.documents.push(doc);
    
        // don't add an unload event for the main document
        // so that the page may be cached in browser history
        if (doc !== scope.document) {
          events.add(win, 'unload', scope.onWindowUnload);
        }
    
        signals.fire('add-document', { doc: doc, win: win });
      },
    
      removeDocument: function removeDocument(doc, win) {
        var index = scope.documents.indexOf(doc);
    
        win = win || getWindow(doc);
    
        events.remove(win, 'unload', scope.onWindowUnload);
    
        scope.documents.splice(index, 1);
        events.documents.splice(index, 1);
    
        signals.fire('remove-document', { win: win, doc: doc });
      },
    
      onWindowUnload: function onWindowUnload() {
        scope.removeDocument(this.document, this);
      }
    };
    
    module.exports = scope;
    
    },{"./utils":44,"./utils/Signals":34,"./utils/domObjects":38,"./utils/events":40,"./utils/window":52}],34:[function(require,module,exports){
    "use strict";
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var Signals = function () {
      function Signals() {
        _classCallCheck(this, Signals);
    
        this.listeners = {
          // signalName: [listeners],
        };
      }
    
      Signals.prototype.on = function on(name, listener) {
        if (!this.listeners[name]) {
          this.listeners[name] = [listener];
          return;
        }
    
        this.listeners[name].push(listener);
      };
    
      Signals.prototype.off = function off(name, listener) {
        if (!this.listeners[name]) {
          return;
        }
    
        var index = this.listeners[name].indexOf(listener);
    
        if (index !== -1) {
          this.listeners[name].splice(index, 1);
        }
      };
    
      Signals.prototype.fire = function fire(name, arg) {
        var targetListeners = this.listeners[name];
    
        if (!targetListeners) {
          return;
        }
    
        for (var _i = 0; _i < targetListeners.length; _i++) {
          var _ref;
    
          _ref = targetListeners[_i];
          var listener = _ref;
    
          if (listener(arg, name) === false) {
            return;
          }
        }
      };
    
      return Signals;
    }();
    
    Signals.new = function () {
      return new Signals();
    };
    
    module.exports = Signals;
    
    },{}],35:[function(require,module,exports){
    "use strict";
    
    function contains(array, target) {
      return array.indexOf(target) !== -1;
    }
    
    function merge(target, source) {
      for (var _i = 0; _i < source.length; _i++) {
        var _ref;
    
        _ref = source[_i];
        var item = _ref;
    
        target.push(item);
      }
    
      return target;
    }
    
    module.exports = {
      contains: contains,
      merge: merge
    };
    
    },{}],36:[function(require,module,exports){
    'use strict';
    
    var _require = require('./window'),
        window = _require.window;
    
    var is = require('./is');
    var domObjects = require('./domObjects');
    
    var Element = domObjects.Element;
    var navigator = window.navigator;
    
    var browser = {
      // Does the browser support touch input?
      supportsTouch: !!('ontouchstart' in window || is.function(window.DocumentTouch) && domObjects.document instanceof window.DocumentTouch),
    
      // Does the browser support PointerEvents
      supportsPointerEvent: !!domObjects.PointerEvent,
    
      isIOS: /iP(hone|od|ad)/.test(navigator.platform),
    
      // scrolling doesn't change the result of getClientRects on iOS 7
      isIOS7: /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\d]/.test(navigator.appVersion),
    
      isIe9: /MSIE 9/.test(navigator.userAgent),
    
      // prefix matchesSelector
      prefixedMatchesSelector: 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',
    
      pEventTypes: domObjects.PointerEvent ? domObjects.PointerEvent === window.MSPointerEvent ? {
        up: 'MSPointerUp',
        down: 'MSPointerDown',
        over: 'mouseover',
        out: 'mouseout',
        move: 'MSPointerMove',
        cancel: 'MSPointerCancel'
      } : {
        up: 'pointerup',
        down: 'pointerdown',
        over: 'pointerover',
        out: 'pointerout',
        move: 'pointermove',
        cancel: 'pointercancel'
      } : null,
    
      // because Webkit and Opera still use 'mousewheel' event type
      wheelEvent: 'onmousewheel' in domObjects.document ? 'mousewheel' : 'wheel'
    
    };
    
    // Opera Mobile must be handled differently
    browser.isOperaMobile = navigator.appName === 'Opera' && browser.supportsTouch && navigator.userAgent.match('Presto');
    
    module.exports = browser;
    
    },{"./domObjects":38,"./is":46,"./window":52}],37:[function(require,module,exports){
    'use strict';
    
    var is = require('./is');
    
    module.exports = function clone(source) {
      var dest = {};
      for (var prop in source) {
        if (is.plainObject(source[prop])) {
          dest[prop] = clone(source[prop]);
        } else {
          dest[prop] = source[prop];
        }
      }
      return dest;
    };
    
    },{"./is":46}],38:[function(require,module,exports){
    'use strict';
    
    var domObjects = {};
    var win = require('./window').window;
    
    function blank() {}
    
    domObjects.document = win.document;
    domObjects.DocumentFragment = win.DocumentFragment || blank;
    domObjects.SVGElement = win.SVGElement || blank;
    domObjects.SVGSVGElement = win.SVGSVGElement || blank;
    domObjects.SVGElementInstance = win.SVGElementInstance || blank;
    domObjects.Element = win.Element || blank;
    domObjects.HTMLElement = win.HTMLElement || domObjects.Element;
    
    domObjects.Event = win.Event;
    domObjects.Touch = win.Touch || blank;
    domObjects.PointerEvent = win.PointerEvent || win.MSPointerEvent;
    
    module.exports = domObjects;
    
    },{"./window":52}],39:[function(require,module,exports){
    'use strict';
    
    var win = require('./window');
    var browser = require('./browser');
    var is = require('./is');
    var domObjects = require('./domObjects');
    
    var domUtils = {
      nodeContains: function nodeContains(parent, child) {
        while (child) {
          if (child === parent) {
            return true;
          }
    
          child = child.parentNode;
        }
    
        return false;
      },
    
      closest: function closest(element, selector) {
        while (is.element(element)) {
          if (domUtils.matchesSelector(element, selector)) {
            return element;
          }
    
          element = domUtils.parentNode(element);
        }
    
        return null;
      },
    
      parentNode: function parentNode(node) {
        var parent = node.parentNode;
    
        if (is.docFrag(parent)) {
          // skip past #shado-root fragments
          while ((parent = parent.host) && is.docFrag(parent)) {
            continue;
          }
    
          return parent;
        }
    
        return parent;
      },
    
      matchesSelector: function matchesSelector(element, selector) {
        // remove /deep/ from selectors if shadowDOM polyfill is used
        if (win.window !== win.realWindow) {
          selector = selector.replace(/\/deep\//g, ' ');
        }
    
        return element[browser.prefixedMatchesSelector](selector);
      },
    
      // Test for the element that's "above" all other qualifiers
      indexOfDeepestElement: function indexOfDeepestElement(elements) {
        var deepestZoneParents = [];
        var dropzoneParents = [];
        var dropzone = void 0;
        var deepestZone = elements[0];
        var index = deepestZone ? 0 : -1;
        var parent = void 0;
        var child = void 0;
        var i = void 0;
        var n = void 0;
    
        for (i = 1; i < elements.length; i++) {
          dropzone = elements[i];
    
          // an element might belong to multiple selector dropzones
          if (!dropzone || dropzone === deepestZone) {
            continue;
          }
    
          if (!deepestZone) {
            deepestZone = dropzone;
            index = i;
            continue;
          }
    
          // check if the deepest or current are document.documentElement or document.rootElement
          // - if the current dropzone is, do nothing and continue
          if (dropzone.parentNode === dropzone.ownerDocument) {
            continue;
          }
          // - if deepest is, update with the current dropzone and continue to next
          else if (deepestZone.parentNode === dropzone.ownerDocument) {
              deepestZone = dropzone;
              index = i;
              continue;
            }
    
          if (!deepestZoneParents.length) {
            parent = deepestZone;
            while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {
              deepestZoneParents.unshift(parent);
              parent = parent.parentNode;
            }
          }
    
          // if this element is an svg element and the current deepest is
          // an HTMLElement
          if (deepestZone instanceof domObjects.HTMLElement && dropzone instanceof domObjects.SVGElement && !(dropzone instanceof domObjects.SVGSVGElement)) {
    
            if (dropzone === deepestZone.parentNode) {
              continue;
            }
    
            parent = dropzone.ownerSVGElement;
          } else {
            parent = dropzone;
          }
    
          dropzoneParents = [];
    
          while (parent.parentNode !== parent.ownerDocument) {
            dropzoneParents.unshift(parent);
            parent = parent.parentNode;
          }
    
          n = 0;
    
          // get (position of last common ancestor) + 1
          while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {
            n++;
          }
    
          var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];
    
          child = parents[0].lastChild;
    
          while (child) {
            if (child === parents[1]) {
              deepestZone = dropzone;
              index = i;
              deepestZoneParents = [];
    
              break;
            } else if (child === parents[2]) {
              break;
            }
    
            child = child.previousSibling;
          }
        }
    
        return index;
      },
    
      matchesUpTo: function matchesUpTo(element, selector, limit) {
        while (is.element(element)) {
          if (domUtils.matchesSelector(element, selector)) {
            return true;
          }
    
          element = domUtils.parentNode(element);
    
          if (element === limit) {
            return domUtils.matchesSelector(element, selector);
          }
        }
    
        return false;
      },
    
      getActualElement: function getActualElement(element) {
        return element instanceof domObjects.SVGElementInstance ? element.correspondingUseElement : element;
      },
    
      getScrollXY: function getScrollXY(relevantWindow) {
        relevantWindow = relevantWindow || win.window;
        return {
          x: relevantWindow.scrollX || relevantWindow.document.documentElement.scrollLeft,
          y: relevantWindow.scrollY || relevantWindow.document.documentElement.scrollTop
        };
      },
    
      getElementClientRect: function getElementClientRect(element) {
        var clientRect = element instanceof domObjects.SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];
    
        return clientRect && {
          left: clientRect.left,
          right: clientRect.right,
          top: clientRect.top,
          bottom: clientRect.bottom,
          width: clientRect.width || clientRect.right - clientRect.left,
          height: clientRect.height || clientRect.bottom - clientRect.top
        };
      },
    
      getElementRect: function getElementRect(element) {
        var clientRect = domUtils.getElementClientRect(element);
    
        if (!browser.isIOS7 && clientRect) {
          var scroll = domUtils.getScrollXY(win.getWindow(element));
    
          clientRect.left += scroll.x;
          clientRect.right += scroll.x;
          clientRect.top += scroll.y;
          clientRect.bottom += scroll.y;
        }
    
        return clientRect;
      },
    
      getPath: function getPath(element) {
        var path = [];
    
        while (element) {
          path.push(element);
          element = domUtils.parentNode(element);
        }
    
        return path;
      },
    
      trySelector: function trySelector(value) {
        if (!is.string(value)) {
          return false;
        }
    
        // an exception will be raised if it is invalid
        domObjects.document.querySelector(value);
        return true;
      }
    };
    
    module.exports = domUtils;
    
    },{"./browser":36,"./domObjects":38,"./is":46,"./window":52}],40:[function(require,module,exports){
    'use strict';
    
    var is = require('./is');
    var domUtils = require('./domUtils');
    var pointerUtils = require('./pointerUtils');
    var pExtend = require('./pointerExtend');
    
    var _require = require('./window'),
        window = _require.window;
    
    var _require2 = require('./arr'),
        contains = _require2.contains;
    
    var elements = [];
    var targets = [];
    
    // {
    //   type: {
    //     selectors: ['selector', ...],
    //     contexts : [document, ...],
    //     listeners: [[listener, capture, passive], ...]
    //   }
    //  }
    var delegatedEvents = {};
    var documents = [];
    
    var supportsOptions = function () {
      var supported = false;
    
      window.document.createElement('div').addEventListener('test', null, {
        get capture() {
          supported = true;
        }
      });
    
      return supported;
    }();
    
    function add(element, type, listener, optionalArg) {
      var options = getOptions(optionalArg);
      var elementIndex = elements.indexOf(element);
      var target = targets[elementIndex];
    
      if (!target) {
        target = {
          events: {},
          typeCount: 0
        };
    
        elementIndex = elements.push(element) - 1;
        targets.push(target);
      }
    
      if (!target.events[type]) {
        target.events[type] = [];
        target.typeCount++;
      }
    
      if (!contains(target.events[type], listener)) {
        element.addEventListener(type, listener, supportsOptions ? options : !!options.capture);
        target.events[type].push(listener);
      }
    }
    
    function remove(element, type, listener, optionalArg) {
      var options = getOptions(optionalArg);
      var elementIndex = elements.indexOf(element);
      var target = targets[elementIndex];
    
      if (!target || !target.events) {
        return;
      }
    
      if (type === 'all') {
        for (type in target.events) {
          if (target.events.hasOwnProperty(type)) {
            remove(element, type, 'all');
          }
        }
        return;
      }
    
      if (target.events[type]) {
        var len = target.events[type].length;
    
        if (listener === 'all') {
          for (var i = 0; i < len; i++) {
            remove(element, type, target.events[type][i], options);
          }
          return;
        } else {
          for (var _i = 0; _i < len; _i++) {
            if (target.events[type][_i] === listener) {
              element.removeEventListener('on' + type, listener, supportsOptions ? options : !!options.capture);
              target.events[type].splice(_i, 1);
    
              break;
            }
          }
        }
    
        if (target.events[type] && target.events[type].length === 0) {
          target.events[type] = null;
          target.typeCount--;
        }
      }
    
      if (!target.typeCount) {
        targets.splice(elementIndex, 1);
        elements.splice(elementIndex, 1);
      }
    }
    
    function addDelegate(selector, context, type, listener, optionalArg) {
      var options = getOptions(optionalArg);
      if (!delegatedEvents[type]) {
        delegatedEvents[type] = {
          selectors: [],
          contexts: [],
          listeners: []
        };
    
        // add delegate listener functions
        for (var _i2 = 0; _i2 < documents.length; _i2++) {
          var doc = documents[_i2];
          add(doc, type, delegateListener);
          add(doc, type, delegateUseCapture, true);
        }
      }
    
      var delegated = delegatedEvents[type];
      var index = void 0;
    
      for (index = delegated.selectors.length - 1; index >= 0; index--) {
        if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {
          break;
        }
      }
    
      if (index === -1) {
        index = delegated.selectors.length;
    
        delegated.selectors.push(selector);
        delegated.contexts.push(context);
        delegated.listeners.push([]);
      }
    
      // keep listener and capture and passive flags
      delegated.listeners[index].push([listener, !!options.capture, options.passive]);
    }
    
    function removeDelegate(selector, context, type, listener, optionalArg) {
      var options = getOptions(optionalArg);
      var delegated = delegatedEvents[type];
      var matchFound = false;
      var index = void 0;
    
      if (!delegated) {
        return;
      }
    
      // count from last index of delegated to 0
      for (index = delegated.selectors.length - 1; index >= 0; index--) {
        // look for matching selector and context Node
        if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {
    
          var listeners = delegated.listeners[index];
    
          // each item of the listeners array is an array: [function, capture, passive]
          for (var i = listeners.length - 1; i >= 0; i--) {
            var _listeners$i = listeners[i],
                fn = _listeners$i[0],
                capture = _listeners$i[1],
                passive = _listeners$i[2];
    
            // check if the listener functions and capture and passive flags match
    
            if (fn === listener && capture === !!options.capture && passive === options.passive) {
              // remove the listener from the array of listeners
              listeners.splice(i, 1);
    
              // if all listeners for this interactable have been removed
              // remove the interactable from the delegated arrays
              if (!listeners.length) {
                delegated.selectors.splice(index, 1);
                delegated.contexts.splice(index, 1);
                delegated.listeners.splice(index, 1);
    
                // remove delegate function from context
                remove(context, type, delegateListener);
                remove(context, type, delegateUseCapture, true);
    
                // remove the arrays if they are empty
                if (!delegated.selectors.length) {
                  delegatedEvents[type] = null;
                }
              }
    
              // only remove one listener
              matchFound = true;
              break;
            }
          }
    
          if (matchFound) {
            break;
          }
        }
      }
    }
    
    // bound to the interactable context when a DOM event
    // listener is added to a selector interactable
    function delegateListener(event, optionalArg) {
      var options = getOptions(optionalArg);
      var fakeEvent = {};
      var delegated = delegatedEvents[event.type];
    
      var _pointerUtils$getEven = pointerUtils.getEventTargets(event),
          eventTarget = _pointerUtils$getEven[0];
    
      var element = eventTarget;
    
      // duplicate the event so that currentTarget can be changed
      pExtend(fakeEvent, event);
    
      fakeEvent.originalEvent = event;
      fakeEvent.preventDefault = preventOriginalDefault;
    
      // climb up document tree looking for selector matches
      while (is.element(element)) {
        for (var i = 0; i < delegated.selectors.length; i++) {
          var selector = delegated.selectors[i];
          var context = delegated.contexts[i];
    
          if (domUtils.matchesSelector(element, selector) && domUtils.nodeContains(context, eventTarget) && domUtils.nodeContains(context, element)) {
    
            var listeners = delegated.listeners[i];
    
            fakeEvent.currentTarget = element;
    
            for (var j = 0; j < listeners.length; j++) {
              var _listeners$j = listeners[j],
                  fn = _listeners$j[0],
                  capture = _listeners$j[1],
                  passive = _listeners$j[2];
    
    
              if (capture === !!options.capture && passive === options.passive) {
                fn(fakeEvent);
              }
            }
          }
        }
    
        element = domUtils.parentNode(element);
      }
    }
    
    function delegateUseCapture(event) {
      return delegateListener.call(this, event, true);
    }
    
    function preventOriginalDefault() {
      this.originalEvent.preventDefault();
    }
    
    function getOptions(param) {
      return is.object(param) ? param : { capture: param };
    }
    
    module.exports = {
      add: add,
      remove: remove,
    
      addDelegate: addDelegate,
      removeDelegate: removeDelegate,
    
      delegateListener: delegateListener,
      delegateUseCapture: delegateUseCapture,
      delegatedEvents: delegatedEvents,
      documents: documents,
    
      supportsOptions: supportsOptions,
    
      _elements: elements,
      _targets: targets
    };
    
    },{"./arr":35,"./domUtils":39,"./is":46,"./pointerExtend":48,"./pointerUtils":49,"./window":52}],41:[function(require,module,exports){
    "use strict";
    
    module.exports = function extend(dest, source) {
      for (var prop in source) {
        dest[prop] = source[prop];
      }
      return dest;
    };
    
    },{}],42:[function(require,module,exports){
    'use strict';
    
    var _require = require('./rect'),
        resolveRectLike = _require.resolveRectLike,
        rectToXY = _require.rectToXY;
    
    module.exports = function (target, element, action) {
      var actionOptions = target.options[action];
      var actionOrigin = actionOptions && actionOptions.origin;
      var origin = actionOrigin || target.options.origin;
    
      var originRect = resolveRectLike(origin, target, element, [target && element]);
    
      return rectToXY(originRect) || { x: 0, y: 0 };
    };
    
    },{"./rect":51}],43:[function(require,module,exports){
    "use strict";
    
    module.exports = function (x, y) {
      return Math.sqrt(x * x + y * y);
    };
    
    },{}],44:[function(require,module,exports){
    'use strict';
    
    var extend = require('./extend');
    var win = require('./window');
    
    var utils = {
      warnOnce: function warnOnce(method, message) {
        var warned = false;
    
        return function () {
          if (!warned) {
            win.window.console.warn(message);
            warned = true;
          }
    
          return method.apply(this, arguments);
        };
      },
    
      // http://stackoverflow.com/a/5634528/2280888
      _getQBezierValue: function _getQBezierValue(t, p1, p2, p3) {
        var iT = 1 - t;
        return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;
      },
    
      getQuadraticCurvePoint: function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {
        return {
          x: utils._getQBezierValue(position, startX, cpX, endX),
          y: utils._getQBezierValue(position, startY, cpY, endY)
        };
      },
    
      // http://gizma.com/easing/
      easeOutQuad: function easeOutQuad(t, b, c, d) {
        t /= d;
        return -c * t * (t - 2) + b;
      },
    
      copyAction: function copyAction(dest, src) {
        dest.name = src.name;
        dest.axis = src.axis;
        dest.edges = src.edges;
    
        return dest;
      },
    
      is: require('./is'),
      extend: extend,
      hypot: require('./hypot'),
      getOriginXY: require('./getOriginXY')
    };
    
    extend(utils, require('./arr'));
    extend(utils, require('./domUtils'));
    extend(utils, require('./pointerUtils'));
    extend(utils, require('./rect'));
    
    module.exports = utils;
    
    },{"./arr":35,"./domUtils":39,"./extend":41,"./getOriginXY":42,"./hypot":43,"./is":46,"./pointerUtils":49,"./rect":51,"./window":52}],45:[function(require,module,exports){
    'use strict';
    
    var scope = require('../scope');
    var utils = require('./index');
    
    var finder = {
      methodOrder: ['simulationResume', 'mouseOrPen', 'hasPointer', 'idle'],
    
      search: function search(pointer, eventType, eventTarget) {
        var pointerType = utils.getPointerType(pointer);
        var pointerId = utils.getPointerId(pointer);
        var details = { pointer: pointer, pointerId: pointerId, pointerType: pointerType, eventType: eventType, eventTarget: eventTarget };
    
        for (var _i = 0; _i < finder.methodOrder.length; _i++) {
          var _ref;
    
          _ref = finder.methodOrder[_i];
          var method = _ref;
    
          var interaction = finder[method](details);
    
          if (interaction) {
            return interaction;
          }
        }
      },
    
      // try to resume simulation with a new pointer
      simulationResume: function simulationResume(_ref2) {
        var pointerType = _ref2.pointerType,
            eventType = _ref2.eventType,
            eventTarget = _ref2.eventTarget;
    
        if (!/down|start/i.test(eventType)) {
          return null;
        }
    
        for (var _i2 = 0; _i2 < scope.interactions.length; _i2++) {
          var _ref3;
    
          _ref3 = scope.interactions[_i2];
          var interaction = _ref3;
    
          var element = eventTarget;
    
          if (interaction.simulation && interaction.simulation.allowResume && interaction.pointerType === pointerType) {
            while (element) {
              // if the element is the interaction element
              if (element === interaction.element) {
                return interaction;
              }
              element = utils.parentNode(element);
            }
          }
        }
    
        return null;
      },
    
      // if it's a mouse or pen interaction
      mouseOrPen: function mouseOrPen(_ref4) {
        var pointerId = _ref4.pointerId,
            pointerType = _ref4.pointerType,
            eventType = _ref4.eventType;
    
        if (pointerType !== 'mouse' && pointerType !== 'pen') {
          return null;
        }
    
        var firstNonActive = void 0;
    
        for (var _i3 = 0; _i3 < scope.interactions.length; _i3++) {
          var _ref5;
    
          _ref5 = scope.interactions[_i3];
          var interaction = _ref5;
    
          if (interaction.pointerType === pointerType) {
            // if it's a down event, skip interactions with running simulations
            if (interaction.simulation && !utils.contains(interaction.pointerIds, pointerId)) {
              continue;
            }
    
            // if the interaction is active, return it immediately
            if (interaction.interacting()) {
              return interaction;
            }
            // otherwise save it and look for another active interaction
            else if (!firstNonActive) {
                firstNonActive = interaction;
              }
          }
        }
    
        // if no active mouse interaction was found use the first inactive mouse
        // interaction
        if (firstNonActive) {
          return firstNonActive;
        }
    
        // find any mouse or pen interaction.
        // ignore the interaction if the eventType is a *down, and a simulation
        // is active
        for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {
          var _ref6;
    
          _ref6 = scope.interactions[_i4];
          var _interaction = _ref6;
    
          if (_interaction.pointerType === pointerType && !(/down/i.test(eventType) && _interaction.simulation)) {
            return _interaction;
          }
        }
    
        return null;
      },
    
      // get interaction that has this pointer
      hasPointer: function hasPointer(_ref7) {
        var pointerId = _ref7.pointerId;
    
        for (var _i5 = 0; _i5 < scope.interactions.length; _i5++) {
          var _ref8;
    
          _ref8 = scope.interactions[_i5];
          var interaction = _ref8;
    
          if (utils.contains(interaction.pointerIds, pointerId)) {
            return interaction;
          }
        }
      },
    
      // get first idle interaction with a matching pointerType
      idle: function idle(_ref9) {
        var pointerType = _ref9.pointerType;
    
        for (var _i6 = 0; _i6 < scope.interactions.length; _i6++) {
          var _ref10;
    
          _ref10 = scope.interactions[_i6];
          var interaction = _ref10;
    
          // if there's already a pointer held down
          if (interaction.pointerIds.length === 1) {
            var target = interaction.target;
            // don't add this pointer if there is a target interactable and it
            // isn't gesturable
            if (target && !target.options.gesture.enabled) {
              continue;
            }
          }
          // maximum of 2 pointers per interaction
          else if (interaction.pointerIds.length >= 2) {
              continue;
            }
    
          if (!interaction.interacting() && pointerType === interaction.pointerType) {
            return interaction;
          }
        }
    
        return null;
      }
    };
    
    module.exports = finder;
    
    },{"../scope":33,"./index":44}],46:[function(require,module,exports){
    'use strict';
    
    var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
    
    var win = require('./window');
    var isWindow = require('./isWindow');
    
    var is = {
      array: function array() {},
    
      window: function window(thing) {
        return thing === win.window || isWindow(thing);
      },
    
      docFrag: function docFrag(thing) {
        return is.object(thing) && thing.nodeType === 11;
      },
    
      object: function object(thing) {
        return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';
      },
    
      function: function _function(thing) {
        return typeof thing === 'function';
      },
    
      number: function number(thing) {
        return typeof thing === 'number';
      },
    
      bool: function bool(thing) {
        return typeof thing === 'boolean';
      },
    
      string: function string(thing) {
        return typeof thing === 'string';
      },
    
      element: function element(thing) {
        if (!thing || (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) !== 'object') {
          return false;
        }
    
        var _window = win.getWindow(thing) || win.window;
    
        return (/object|function/.test(_typeof(_window.Element)) ? thing instanceof _window.Element //DOM2
          : thing.nodeType === 1 && typeof thing.nodeName === 'string'
        );
      },
    
      plainObject: function plainObject(thing) {
        return is.object(thing) && thing.constructor.name === 'Object';
      }
    };
    
    is.array = function (thing) {
      return is.object(thing) && typeof thing.length !== 'undefined' && is.function(thing.splice);
    };
    
    module.exports = is;
    
    },{"./isWindow":47,"./window":52}],47:[function(require,module,exports){
    "use strict";
    
    module.exports = function (thing) {
      return !!(thing && thing.Window) && thing instanceof thing.Window;
    };
    
    },{}],48:[function(require,module,exports){
    'use strict';
    
    function pointerExtend(dest, source) {
      for (var prop in source) {
        var prefixedPropREs = module.exports.prefixedPropREs;
        var deprecated = false;
    
        // skip deprecated prefixed properties
        for (var vendor in prefixedPropREs) {
          if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {
            deprecated = true;
            break;
          }
        }
    
        if (!deprecated && typeof source[prop] !== 'function') {
          dest[prop] = source[prop];
        }
      }
      return dest;
    }
    
    pointerExtend.prefixedPropREs = {
      webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/
    };
    
    module.exports = pointerExtend;
    
    },{}],49:[function(require,module,exports){
    'use strict';
    
    var hypot = require('./hypot');
    var browser = require('./browser');
    var dom = require('./domObjects');
    var domUtils = require('./domUtils');
    var domObjects = require('./domObjects');
    var is = require('./is');
    var pointerExtend = require('./pointerExtend');
    
    var pointerUtils = {
      copyCoords: function copyCoords(dest, src) {
        dest.page = dest.page || {};
        dest.page.x = src.page.x;
        dest.page.y = src.page.y;
    
        dest.client = dest.client || {};
        dest.client.x = src.client.x;
        dest.client.y = src.client.y;
    
        dest.timeStamp = src.timeStamp;
      },
    
      setCoordDeltas: function setCoordDeltas(targetObj, prev, cur) {
        targetObj.page.x = cur.page.x - prev.page.x;
        targetObj.page.y = cur.page.y - prev.page.y;
        targetObj.client.x = cur.client.x - prev.client.x;
        targetObj.client.y = cur.client.y - prev.client.y;
        targetObj.timeStamp = cur.timeStamp - prev.timeStamp;
    
        // set pointer velocity
        var dt = Math.max(targetObj.timeStamp / 1000, 0.001);
    
        targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;
        targetObj.page.vx = targetObj.page.x / dt;
        targetObj.page.vy = targetObj.page.y / dt;
    
        targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;
        targetObj.client.vx = targetObj.client.x / dt;
        targetObj.client.vy = targetObj.client.y / dt;
      },
    
      isNativePointer: function isNativePointer(pointer) {
        return pointer instanceof dom.Event || pointer instanceof dom.Touch;
      },
    
      // Get specified X/Y coords for mouse or event.touches[0]
      getXY: function getXY(type, pointer, xy) {
        xy = xy || {};
        type = type || 'page';
    
        xy.x = pointer[type + 'X'];
        xy.y = pointer[type + 'Y'];
    
        return xy;
      },
    
      getPageXY: function getPageXY(pointer, page) {
        page = page || {};
    
        // Opera Mobile handles the viewport and scrolling oddly
        if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {
          pointerUtils.getXY('screen', pointer, page);
    
          page.x += window.scrollX;
          page.y += window.scrollY;
        } else {
          pointerUtils.getXY('page', pointer, page);
        }
    
        return page;
      },
    
      getClientXY: function getClientXY(pointer, client) {
        client = client || {};
    
        if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {
          // Opera Mobile handles the viewport and scrolling oddly
          pointerUtils.getXY('screen', pointer, client);
        } else {
          pointerUtils.getXY('client', pointer, client);
        }
    
        return client;
      },
    
      getPointerId: function getPointerId(pointer) {
        return is.number(pointer.pointerId) ? pointer.pointerId : pointer.identifier;
      },
    
      setCoords: function setCoords(targetObj, pointers, timeStamp) {
        var pointer = pointers.length > 1 ? pointerUtils.pointerAverage(pointers) : pointers[0];
    
        var tmpXY = {};
    
        pointerUtils.getPageXY(pointer, tmpXY);
        targetObj.page.x = tmpXY.x;
        targetObj.page.y = tmpXY.y;
    
        pointerUtils.getClientXY(pointer, tmpXY);
        targetObj.client.x = tmpXY.x;
        targetObj.client.y = tmpXY.y;
    
        targetObj.timeStamp = is.number(timeStamp) ? timeStamp : new Date().getTime();
      },
    
      pointerExtend: pointerExtend,
    
      getTouchPair: function getTouchPair(event) {
        var touches = [];
    
        // array of touches is supplied
        if (is.array(event)) {
          touches[0] = event[0];
          touches[1] = event[1];
        }
        // an event
        else {
            if (event.type === 'touchend') {
              if (event.touches.length === 1) {
                touches[0] = event.touches[0];
                touches[1] = event.changedTouches[0];
              } else if (event.touches.length === 0) {
                touches[0] = event.changedTouches[0];
                touches[1] = event.changedTouches[1];
              }
            } else {
              touches[0] = event.touches[0];
              touches[1] = event.touches[1];
            }
          }
    
        return touches;
      },
    
      pointerAverage: function pointerAverage(pointers) {
        var average = {
          pageX: 0,
          pageY: 0,
          clientX: 0,
          clientY: 0,
          screenX: 0,
          screenY: 0
        };
    
        for (var _i = 0; _i < pointers.length; _i++) {
          var _ref;
    
          _ref = pointers[_i];
          var pointer = _ref;
    
          for (var _prop in average) {
            average[_prop] += pointer[_prop];
          }
        }
        for (var prop in average) {
          average[prop] /= pointers.length;
        }
    
        return average;
      },
    
      touchBBox: function touchBBox(event) {
        if (!event.length && !(event.touches && event.touches.length > 1)) {
          return;
        }
    
        var touches = pointerUtils.getTouchPair(event);
        var minX = Math.min(touches[0].pageX, touches[1].pageX);
        var minY = Math.min(touches[0].pageY, touches[1].pageY);
        var maxX = Math.max(touches[0].pageX, touches[1].pageX);
        var maxY = Math.max(touches[0].pageY, touches[1].pageY);
    
        return {
          x: minX,
          y: minY,
          left: minX,
          top: minY,
          width: maxX - minX,
          height: maxY - minY
        };
      },
    
      touchDistance: function touchDistance(event, deltaSource) {
        var sourceX = deltaSource + 'X';
        var sourceY = deltaSource + 'Y';
        var touches = pointerUtils.getTouchPair(event);
    
        var dx = touches[0][sourceX] - touches[1][sourceX];
        var dy = touches[0][sourceY] - touches[1][sourceY];
    
        return hypot(dx, dy);
      },
    
      touchAngle: function touchAngle(event, prevAngle, deltaSource) {
        var sourceX = deltaSource + 'X';
        var sourceY = deltaSource + 'Y';
        var touches = pointerUtils.getTouchPair(event);
        var dx = touches[1][sourceX] - touches[0][sourceX];
        var dy = touches[1][sourceY] - touches[0][sourceY];
        var angle = 180 * Math.atan2(dy, dx) / Math.PI;
    
        return angle;
      },
    
      getPointerType: function getPointerType(pointer) {
        return is.string(pointer.pointerType) ? pointer.pointerType : is.number(pointer.pointerType) ? [undefined, undefined, 'touch', 'pen', 'mouse'][pointer.pointerType]
        // if the PointerEvent API isn't available, then the "pointer" must
        // be either a MouseEvent, TouchEvent, or Touch object
        : /touch/.test(pointer.type) || pointer instanceof domObjects.Touch ? 'touch' : 'mouse';
      },
    
      // [ event.target, event.currentTarget ]
      getEventTargets: function getEventTargets(event) {
        var path = is.function(event.composedPath) ? event.composedPath() : event.path;
    
        return [domUtils.getActualElement(path ? path[0] : event.target), domUtils.getActualElement(event.currentTarget)];
      }
    };
    
    module.exports = pointerUtils;
    
    },{"./browser":36,"./domObjects":38,"./domUtils":39,"./hypot":43,"./is":46,"./pointerExtend":48}],50:[function(require,module,exports){
    'use strict';
    
    var _require = require('./window'),
        window = _require.window;
    
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    var lastTime = 0;
    var request = void 0;
    var cancel = void 0;
    
    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {
      request = window[vendors[x] + 'RequestAnimationFrame'];
      cancel = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
    }
    
    if (!request) {
      request = function request(callback) {
        var currTime = new Date().getTime();
        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
        var id = setTimeout(function () {
          callback(currTime + timeToCall);
        }, timeToCall);
    
        lastTime = currTime + timeToCall;
        return id;
      };
    }
    
    if (!cancel) {
      cancel = function cancel(id) {
        clearTimeout(id);
      };
    }
    
    module.exports = {
      request: request,
      cancel: cancel
    };
    
    },{"./window":52}],51:[function(require,module,exports){
    'use strict';
    
    var extend = require('./extend');
    var is = require('./is');
    
    var _require = require('./domUtils'),
        closest = _require.closest,
        parentNode = _require.parentNode,
        getElementRect = _require.getElementRect;
    
    var rectUtils = {
      getStringOptionResult: function getStringOptionResult(value, interactable, element) {
        if (!is.string(value)) {
          return null;
        }
    
        if (value === 'parent') {
          value = parentNode(element);
        } else if (value === 'self') {
          value = interactable.getRect(element);
        } else {
          value = closest(element, value);
        }
    
        return value;
      },
    
      resolveRectLike: function resolveRectLike(value, interactable, element, functionArgs) {
        value = rectUtils.getStringOptionResult(value, interactable, element) || value;
    
        if (is.function(value)) {
          value = value.apply(null, functionArgs);
        }
    
        if (is.element(value)) {
          value = getElementRect(value);
        }
    
        return value;
      },
    
      rectToXY: function rectToXY(rect) {
        return rect && {
          x: 'x' in rect ? rect.x : rect.left,
          y: 'y' in rect ? rect.y : rect.top
        };
      },
    
      xywhToTlbr: function xywhToTlbr(rect) {
        if (rect && !('left' in rect && 'top' in rect)) {
          rect = extend({}, rect);
    
          rect.left = rect.x || 0;
          rect.top = rect.y || 0;
          rect.right = rect.right || rect.left + rect.width;
          rect.bottom = rect.bottom || rect.top + rect.height;
        }
    
        return rect;
      },
    
      tlbrToXywh: function tlbrToXywh(rect) {
        if (rect && !('x' in rect && 'y' in rect)) {
          rect = extend({}, rect);
    
          rect.x = rect.left || 0;
          rect.top = rect.top || 0;
          rect.width = rect.width || rect.right - rect.x;
          rect.height = rect.height || rect.bottom - rect.y;
        }
    
        return rect;
      }
    };
    
    module.exports = rectUtils;
    
    },{"./domUtils":39,"./extend":41,"./is":46}],52:[function(require,module,exports){
    'use strict';
    
    var win = module.exports;
    var isWindow = require('./isWindow');
    
    function init(window) {
      // get wrapped window if using Shadow DOM polyfill
    
      win.realWindow = window;
    
      // create a TextNode
      var el = window.document.createTextNode('');
    
      // check if it's wrapped by a polyfill
      if (el.ownerDocument !== window.document && typeof window.wrap === 'function' && window.wrap(el) === el) {
        // use wrapped window
        window = window.wrap(window);
      }
    
      win.window = window;
    }
    
    if (typeof window === 'undefined') {
      win.window = undefined;
      win.realWindow = undefined;
    } else {
      init(window);
    }
    
    win.getWindow = function getWindow(node) {
      if (isWindow(node)) {
        return node;
      }
    
      var rootNode = node.ownerDocument || node;
    
      return rootNode.defaultView || rootNode.parentWindow || win.window;
    };
    
    win.init = init;
    
    },{"./isWindow":47}]},{},[1])(1)
    });
    
    
    //# sourceMappingURL=interact.js.map